Détection D'une instance de Date" non valide " dans JavaScript

j'aimerais faire la différence entre les objets datation valides et invalides dans JS, mais je n'ai pas trouvé comment:

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

des idées pour écrire une fonction isValidDate ?

  • Ash recommandé Date.parse pour l'analyse des chaînes date, ce qui donne une autorité moyen de vérifier si la date est valide.
  • ce que je préférerais, si possible, c'est que mon API accepte une instance de Date et puisse pour vérifier/vérifie si elle est valide ou pas. La solution de Borgar fait ça, mais je dois le tester sur tous les navigateurs. Je me demande aussi s'il y a un moyen plus élégant.
  • Ash m'a fait considérer ne pas avoir mon API accepter Date instances à tous, ce serait plus facile à valider.
  • Borgar suggère de tester une instance Date , puis de tester la valeur temporelle de Date . Si la date n'est pas valide, la valeur temporelle est NaN . Je vérifié avec ECMA-262 et ce comportement est dans la norme, qui est exactement ce que je cherche.
1124
demandé sur Servy 2009-08-30 15:34:40

30 réponses

Voici comment j'allais le faire:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d.getTime())) {  // d.valueOf() could also work
    // date is not valid
  } else {
    // date is valid
  }
} else {
  // not a date
}

mise à jour [2018-05-31] : si vous n'êtes pas concerné par les objets Date provenant d'autres contextes JS (fenêtres externes, cadres, ou iframes), cette forme plus simple peut être préférée:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}
923
répondu Borgar 2018-05-31 19:00:42

au Lieu d'utiliser new Date() vous devez utiliser:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse() renvoie une estampille temporelle, un entier représentant le nombre de millisecondes depuis le 01/Jan/1970. Il retournera NaN s'il ne peut pas analyser la chaîne de date fournie.

214
répondu Ash 2018-04-10 20:01:36

Vous pouvez vérifier la validité d'un Date objet d via

d instanceof Date && isFinite(d)

pour éviter les problèmes de cross-frame, on pourrait remplacer le instanceof check par

Object.prototype.toString.call(d) === '[object Date]'

un appel à getTime() comme dans réponse de Borgar est inutile comme isNaN() et isFinite() les deux se convertissent implicitement en nombre.

91
répondu Christoph 2017-05-23 12:02:46

ma solution consiste simplement à vérifier si vous obtenez un objet date valide:

mise en œuvre

Date.prototype.isValid = function () {
    // An invalid date object returns NaN for getTime() and NaN is the only
    // object not strictly equal to itself.
    return this.getTime() === this.getTime();
};  

Utilisation

var d = new Date("lol");

console.log(d.isValid()); // false

d = new Date("2012/09/11");

console.log(d.isValid()); // true
68
répondu Ash Clarke 2012-09-11 15:03:31

réponse la plus courte pour vérifier la date de validité

if(!isNaN(date.getTime()))
59
répondu abhirathore2006 2016-07-04 10:10:05

voudrait mentionner que le widget de datepicker de jQuery UI a une très bonne méthode d'utilité de validateur de date qui vérifie le format et la validité (par exemple, pas de dates 01/33/2013 permises).

même si vous ne voulez pas utiliser le widget de curseur de données sur votre page comme un élément UI, vous pouvez toujours ajouter son .la bibliothèque js à votre page et ensuite appeler la méthode validator, en lui passant la valeur que vous voulez valider. Pour rendre la vie encore plus facile, il faut une chaîne comme entrée, pas un Objet Date JavaScript.

voir: http://api.jqueryui.com/datepicker /

Il n'est pas répertoriée comme une méthode, mais il est là, comme une fonction d'utilité. Recherchez la page pour "parsedate" et vous trouverez:

$.datepicker.parseDate (format, valeur, Paramètres ) - extraire une date à partir d'une valeur de chaîne avec un format spécifié.

exemple d'usage:

var stringval = '01/03/2012';
var testdate;

try {
  testdate = $.datepicker.parseDate('mm/dd/yy', stringval);
             // Notice 'yy' indicates a 4-digit year value
} catch (e)
{
 alert(stringval + ' is not valid.  Format must be MM/DD/YYYY ' +
       'and the date value must be valid for the calendar.';
}

(pour plus d'informations sur les formats de date, voir http://api.jqueryui.com/datepicker/#utility-parseDate )

dans l'exemple ci-dessus, vous ne verriez pas le message d'alerte puisque '01/03/2012' est une date de validité de calendrier dans le format spécifié. Cependant, si vous avez fait 'stringval' égal à' 13/04/2013', par exemple, vous obtiendriez le message d'alerte, puisque la valeur' 13/04/2013 ' n'est pas valide pour le calendrier.

si a la valeur de chaîne de caractères transmise est analysée avec succès, la valeur de "testdate" serait un objet Date Javascript représentant la valeur de chaîne de caractères transmise. Si non, ce serait pas défini.

36
répondu Matt Campbell 2016-07-07 08:35:51

J'ai vraiment aimé L'approche de Christoph (mais je n'avais pas assez de réputation pour voter). Pour mon utilisation, je sais que j'aurai toujours un objet Date, donc j'ai juste prolongé date valide() la méthode.

Date.prototype.valid = function() {
  return isFinite(this);
}

maintenant je peux juste écrire ceci et c'est beaucoup plus descriptif que juste vérifier isFinite dans le code...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
23
répondu broox 2010-11-23 19:47:52
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
15
répondu faridz 2011-07-06 21:27:24

j'utilise le code suivant pour valider les valeurs pour l'année, le mois et la date.

function createDate(year, month, _date) {
  var d = new Date(year, month, _date);
  if (d.getFullYear() != year 
    || d.getMonth() != month
    || d.getDate() != _date) {
    throw "invalid date";
  }
  return d;
}

pour plus de détails, voir Date de contrôle en javascript

15
répondu Jingguo Yao 2016-02-03 08:28:28

trop de réponses compliquées ici déjà, mais une ligne simple est suffisante (ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

ou même en ES6:

Date.prototype.isValid = d => !isNaN(Date.parse(d));
12
répondu Sebastien H. 2017-05-11 12:35:19

vous pouvez vérifier le format valide de txDate.valeur avec ce scirpt. si le format est incorrect, la Date obejct n'est pas instanciée et renvoie null à dt .

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

et comme @MiF l'a suggéré dans short way

 if(isNaN(new Date(...)))
12
répondu zhilevan 2017-10-07 06:50:50

bonne solution! Inclus dans ma bibliothèque de fonctions auxiliaires, maintenant il ressemble à ceci:

Object.isDate = function(obj) {
/// <summary>
/// Determines if the passed object is an instance of Date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.prototype.toString.call(obj) === '[object Date]';
}

Object.isValidDate = function(obj) {
/// <summary>
/// Determines if the passed object is a Date object, containing an actual date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.isDate(obj) && !isNaN(obj.getTime());
}
9
répondu Dmytro Shevchenko 2011-05-03 16:44:25

Pour Angulaire.vous pouvez utiliser les projets js:

angular.isDate(myDate);
9
répondu Nick Taras 2015-09-18 00:27:40

Cette juste a fonctionné pour moi

new Date('foo') == 'Invalid Date'; //is true

Cependant, cela ne marche pas

new Date('foo') === 'Invalid Date'; //is false
6
répondu user1296274 2014-01-06 02:36:02

aucune des solutions ci-dessus n'a fonctionné pour moi ce qui a fonctionné cependant est

function validDate (d) {
        var date = new Date(d);
        var day = ""+date.getDate();
        if( day.length == 1)day = "0"+day;
        var month = "" +( date.getMonth() + 1);
        if( month.length == 1)month = "0"+month;
        var year = "" + date.getFullYear();

        return ((month + "/" + day + "/" + year) == d);
    }

le code ci-dessus verra quand JS fait 31/02/2012 dans 03/02/2012 que son pas valide

5
répondu John 2012-08-31 07:12:22
IsValidDate: function(date) {
        var regex = /\d{1,2}\/\d{1,2}\/\d{4}/;
        if (!regex.test(date)) return false;
        var day = Number(date.split("/")[1]);
        date = new Date(date);
        if (date && date.getDate() != day) return false;
        return true;
}
5
répondu Michael Goldshmidt 2012-09-14 18:52:43

aucune de ces réponses n'a fonctionné pour moi (testé dans Safari 6.0) en essayant de valider une date telle que 31/02/2012, cependant, ils fonctionnent très bien en essayant n'importe quelle date supérieure à 31.

donc j'ai dû forcer un peu. En supposant que la date est dans le format mm/dd/yyyy . J'utilise la réponse de @broox:

Date.prototype.valid = function() {
    return isFinite(this);
}    

function validStringDate(value){
    var d = new Date(value);
    return d.valid() && value.split('/')[0] == (d.getMonth()+1);
}

validStringDate("2/29/2012"); // true (leap year)
validStringDate("2/29/2013"); // false
validStringDate("2/30/2012"); // false
5
répondu Dex 2014-02-01 16:49:38

j'ai écrit cette fonction. Passez-lui un paramètre string et il déterminera s'il s'agit d'une date valide ou non basée sur ce format "JJ/MM/AAAA".

voici un test

entrée: "hahaha",sortie: faux.

entrée: "29/2/2000",sortie: vrai.

entrée: "29/2/2001",sortie: faux.

function isValidDate(str) {
    var parts = str.split('/');
    if (parts.length < 3)
        return false;
    else {
        var day = parseInt(parts[0]);
        var month = parseInt(parts[1]);
        var year = parseInt(parts[2]);
        if (isNaN(day) || isNaN(month) || isNaN(year)) {
            return false;
        }
        if (day < 1 || year < 1)
            return false;
        if(month>12||month<1)
            return false;
        if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)
            return false;
        if ((month == 4 || month == 6 || month == 9 || month == 11 ) && day > 30)
            return false;
        if (month == 2) {
            if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0 && (year % 100) == 0)) {
                if (day > 29)
                    return false;
            } else {
                if (day > 28)
                    return false;
            }      
        }
        return true;
    }
}
4
répondu Yaseen 2014-02-25 11:22:44

inspiré par L'approche de Borgar, j'ai fait en sorte que le code valide non seulement la date, mais en fait s'assure que la date est une date réelle, ce qui signifie que les dates comme 31/09/2011 et 29/02/2011 ne sont pas autorisés.

function(dateStr) {
    s = dateStr.split('/');
    d = new Date(+s[2], s[1]-1, +s[0]);
    if (Object.prototype.toString.call(d) === "[object Date]") {
        if (!isNaN(d.getTime()) && d.getDate() == s[0] && 
            d.getMonth() == (s[1] - 1)) {
            return true;
        }
    }
    return "Invalid date!";
}
3
répondu Raz 2011-08-18 15:52:40

j'ai combiné les meilleurs résultats que j'ai trouvé autour de la vérification si un objet donné:

Le résultat est le suivant:

function isValidDate(input) {
  if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
    return false;

  var time = input.getTime();
  return time === time;
};
3
répondu zVictor 2015-04-30 09:00:39

Date object to string est un moyen plus simple et fiable de détecter si les deux champs sont une date valide. par exemple, si vous entrez ceci"------- " au champ date input. Certaines des réponses ci-dessus ne fonctionne pas.

jQuery.validator.addMethod("greaterThan", 

    function(value, element, params) {
        var startDate = new Date($(params).val());
        var endDate = new Date(value);

        if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {
            return false;
        } else {
            return endDate > startDate;
        }
    },'Must be greater than {0}.');
2
répondu kam 2013-08-12 20:41:35

vous pouvez convertir votre date et l'heure en millisecondes getTime ()

ce getTime() de retour de Méthode n'est Pas un Nombre NaN lorsqu'il n'est pas valide

if(!isNaN(new Date("2012/25/255").getTime()))
  return 'valid date time';
  return 'Not a valid date time';
2
répondu Mina Gabriel 2014-01-31 21:39:49

la réponse choisie est excellente, et je l'utilise aussi. Cependant, si vous êtes à la recherche d'un moyen de valider l'entrée user date, vous devriez être conscient que L'objet Date est très persistant à faire ce qui pourrait sembler être des arguments de construction invalides en arguments valides. Le code d'essai unitaire suivant illustre ce point:

QUnit.test( "valid date test", function( assert ) {
  //The following are counter-examples showing how the Date object will 
  //wrangle several 'bad' dates into a valid date anyway
  assert.equal(isValidDate(new Date(1980, 12, 15)), true);
  d = new Date();
  d.setFullYear(1980);
  d.setMonth(1);
  d.setDate(33);
  assert.equal(isValidDate(d), true);
  assert.equal(isValidDate(new Date(1980, 100, 150)), true);
  //If you go to this exterme, then the checker will fail
  assert.equal(isValidDate(new Date("This is junk")), false);
  //This is a valid date string
  assert.equal(isValidDate(new Date("November 17, 1989")), true);
  //but is this?
  assert.equal(isValidDate(new Date("November 35, 1989")), false);  
  //Ha!  It's not.  So, the secret to working with this version of 
  //isValidDate is to pass in dates as text strings... Hooboy
  //alert(d.toString());
});
2
répondu dolphus333 2014-06-18 18:14:23
function isValidDate(strDate) {
    var myDateStr= new Date(strDate);
    if( ! isNaN ( myDateStr.getMonth() ) ) {
       return true;
    }
    return false;
}

appelez ça comme ça

isValidDate(""2015/5/2""); // => true
isValidDate(""2015/5/2a""); // => false
2
répondu kiranvj 2015-08-23 03:50:30

Un prêt de la fonction basée sur le top rated réponse:

  /**
   * Check if date exists and is valid.
   *
   * @param {String} dateString Date in YYYY-mm-dd format.
   */
  function isValidDate(dateString) {
  var isValid = false;
  var date;

  date =
    new Date(
      dateString);

  if (
    Object.prototype.toString.call(
      date) === "[object Date]") {

    if (isNaN(date.getTime())) {

      // Date is unreal.

    } else {
      // Date is real if month and day match each other in date and string (otherwise may be shifted):
      isValid =
        date.getUTCMonth() + 1 === dateString.split("-")[1] * 1 &&
        date.getUTCDate() === dateString.split("-")[2] * 1;
    }
  } else {
    // It's not a date.
  }

  return isValid;
}
2
répondu Zon 2017-03-21 04:48:29

je pense qu'une partie de ceci est un long processus. Nous pouvons le couper court comme montré ci-dessous:

 function isValidDate(dateString) {
        debugger;
        var dateStringSplit;
        var formatDate;

        if (dateString.length >= 8 && dateString.length<=10) {
            try {
                dateStringSplit = dateString.split('/');
                var date = new Date();
                date.setYear(parseInt(dateStringSplit[2]), 10);
                date.setMonth(parseInt(dateStringSplit[0], 10) - 1);
                date.setDate(parseInt(dateStringSplit[1], 10));

                if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {
                    return true;
                }
                else {
                    return false;
                }

            } catch (e) {
                return false;
            }
        }
        return false;
    }
1
répondu user889209 2011-08-11 16:39:59

pour les composants int 1 d'une date:

var is_valid_date = function(year, month, day) {
    var d = new Date(year, month - 1, day);
    return d.getFullYear() === year && (d.getMonth() + 1) === month && d.getDate() === day
};

Essais:

    is_valid_date(2013, 02, 28)
&&  is_valid_date(2016, 02, 29)
&& !is_valid_date(2013, 02, 29)
&& !is_valid_date(0000, 00, 00)
&& !is_valid_date(2013, 14, 01)
1
répondu Denis Ryzhkov 2013-11-08 12:49:33

en général, je m'en tiendrais à la date d'implantation dans la pile du navigateur. Ce qui signifie que vous obtiendrez toujours "Date invalide" en appelant toDateString() dans Chrome, Firefox, et Safari à partir de la date de cette réponse.

if(!Date.prototype.isValidDate){
  Date.prototype.isValidDate = function(){
    return this.toDateString().toLowerCase().lastIndexOf('invalid') == -1;
  };
}

Je ne l'ai pas testé dans IE si.

1
répondu pixelbacon 2014-08-26 18:51:45
function isValidDate(date) {
  return !! (Object.prototype.toString.call(date) === "[object Date]" && +date);
}
1
répondu Joel Kornbluh 2015-04-23 17:45:06