web-dev-qa-db-fra.com

Comment vérifier si un objet est une date?

J'ai un bug gênant sur une page web:

date.GetMonth () n'est pas une fonction

Donc, je suppose que je fais quelque chose de mal. La variable date n'est pas un objet de type Date. Comment puis-je vérifier un type de données en Javascript? J'ai essayé d'ajouter une if (date), mais cela ne fonctionne pas.

function getFormatedDate(date) {
    if (date) {
       var month = date.GetMonth();
    }
}

Donc, si je veux écrire du code défensif et empêcher la date (qui n'en est pas une) d'être formatée, comment puis-je le faire?

Merci!

PDATE: Je ne veux pas vérifier le format de la date, mais je veux être sûr que le paramètre transmis à la méthode getFormatedDate() est de type Date.

497
Martin

Comme alternative à la frappe de canard via

typeof date.getMonth === 'function'

vous pouvez utiliser l’opérateur instanceof, c’est-à-dire qu’il renverra la valeur true pour les dates non valides également, par exemple. new Date('random_string') est également une instance de Date

date instanceof Date

Cela échouera si les objets sont passés au-delà des limites du cadre.

Une solution pour cela consiste à vérifier la classe de l'objet via

Object.prototype.toString.call(date) === '[object Date]'
966
Christoph

Vous pouvez utiliser le code suivant:

(myvar instanceof Date) // returns true or false
114
SF_dev

Afin de vérifier si la valeur est un type valide de l'objet JS-date standard, vous pouvez utiliser ce prédicat:

_function isValidDate(date) {
  return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
_
  1. date vérifie si le paramètre n'était pas un valeur de fausseté (undefined, null, _0_, _""_, etc ..)
  2. Object.prototype.toString.call(date) renvoie une représentation sous forme de chaîne native du type d'objet donné - Dans notre cas, _"[object Date]"_. Parce que date.toString() remplace sa méthode parente , nous devons .call ou .apply la méthode de _Object.prototype_ directement qui ..
  3. !isNaN(date) vérifie enfin si la valeur n'était pas un _Invalid Date_.
49
Boghyon Hoffmann

La fonction est getMonth() et non GetMonth().

Quoi qu'il en soit, vous pouvez vérifier si l'objet a une propriété getMonth en procédant ainsi. Cela ne signifie pas nécessairement que l'objet est une Date, mais tout objet possédant une propriété getMonth.

if (date.getMonth) {
    var month = date.getMonth();
}
38
Chetan Sastry

Comme indiqué ci-dessus, il est probablement plus facile de vérifier si la fonction existe avant de l'utiliser. Si vous vous souciez vraiment qu'il s'agisse d'un Date , et pas simplement d'un objet avec une fonction getMonth(), essayez ceci:

function isValidDate(value) {
    var dateWrapper = new Date(value);
    return !isNaN(dateWrapper.getDate());
}

Cela créera soit un clone de la valeur s'il s'agit de Date, soit une date non valide. Vous pouvez ensuite vérifier si la valeur de la nouvelle date est invalide ou non.

19
bdukes

Pour tous les types, j'ai concocté une fonction de prototype d'objet. Cela peut vous être utile

Object.prototype.typof = function(chkType){
      var inp        = String(this.constructor),
          customObj  = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9),
          regularObj = Object.prototype.toString.apply(this),
          thisType   = regularObj.toLowerCase()
                        .match(new RegExp(customObj.toLowerCase()))
                       ? regularObj : '[object '+customObj+']';
     return chkType
            ? thisType.toLowerCase().match(chkType.toLowerCase()) 
               ? true : false
            : thisType;
}

Maintenant, vous pouvez vérifier tout type comme ceci:

var myDate     = new Date().toString(),
    myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String

[Edit mars 201] Sur la base de la progression des connaissances, il s'agit d'une meilleure méthode:

Object.prototype.is = function() {
        var test = arguments.length ? [].slice.call(arguments) : null
           ,self = this.constructor;
        return test ? !!(test.filter(function(a){return a === self}).length)
               : (this.constructor.name ||
                  (String(self).match ( /^function\s*([^\s(]+)/im)
                    || [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Some = function(){ /* ... */}
   ,Other = function(){ /* ... */}
   ,some = new Some;
2..is(String,Function,RegExp);        //=> false
2..is(String,Function,Number,RegExp); //=> true
'hello'.is(String);                   //=> true
'hello'.is();                         //-> String
/[a-z]/i.is();                        //-> RegExp
some.is();                            //=> 'ANONYMOUS_CONSTRUCTOR'
some.is(Other);                       //=> false
some.is(Some);                        //=> true
// note: you can't use this for NaN (NaN === Number)
(+'ab2').is(Number);                 //=> true
18
KooiInc

UnderscoreJS et Lodash ont une fonction appelée .isDate() = qui semble être exactement ce dont vous avez besoin. Cela vaut la peine de regarder leurs implémentations respectives: Lodash isDate , nderscoreJs

8
avalanche1

Le meilleur moyen que j'ai trouvé est:

!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001"))  // true
!isNaN(Date.parse("blabla"))  // false
7
jspassov

Vous pouvez vérifier si une fonction spécifique à l'objet Date existe:

function getFormatedDate(date) {
    if (date.getMonth) {
        var month = date.getMonth();
    }
}
3
Powerlord

J'ai utilisé un moyen beaucoup plus simple, mais je ne suis pas sûr si cela est uniquement disponible dans ES6 ou non.

let a = {name: "a", age: 1, date: new Date("1/2/2017"), arr: [], obj: {} };
console.log(a.name.constructor.name); // "String"
console.log(a.age.constructor.name);  // "Number"
console.log(a.date.constructor.name); // "Date"
console.log(a.arr.constructor.name);  // "Array"
console.log(a.obj.constructor.name);  // "Object"

Cependant, cela ne fonctionnera pas sur null ou undefined car ils n'ont pas de constructeur.

2
mjwrazor

Aussi, vous pouvez utiliser la forme abrégée

function getClass(obj) {
  return {}.toString.call(obj).slice(8, -1);
}
alert( getClass(new Date) ); //Date

ou quelque chose comme ça:

(toString.call(date)) == 'Date'
2
pavlo

Cette fonction retournera true s'il s'agit de Date ou false sinon:

function isDate(myDate) {
    return myDate.constructor.toString().indexOf("Date") > -1;
} 
1
Jahid

Une approche utilisant un try/catch

function getFormatedDate(date = new Date()) {
  try {
    date.toISOString();
  } catch (e) {
    date = new Date();
  }
  return date;
}

console.log(getFormatedDate());
console.log(getFormatedDate('AAAA'));
console.log(getFormatedDate(new Date('AAAA')));
console.log(getFormatedDate(new Date(2018, 2, 10)));
0
codeKonami

Au lieu de toutes les solutions de contournement, vous pouvez utiliser les éléments suivants:

dateVariable = new Date(date);
if (dateVariable == 'Invalid Date') console.log('Invalid Date!');

J'ai trouvé ce bidouillage mieux!

0
Harsh

Encore une autre variante:

Date.prototype.isPrototypeOf(myDateObject)
0
Vadim

En fait, la date sera de type Object. Mais vous pouvez vérifier si l'objet a la méthode getMonth et s'il est appelable.

function getFormatedDate(date) {
    if (date && date.getMonth && date.getMonth.call) {
       var month = date.getMonth();
    }
}
0
vartec