Détection d'une instance de date «date non valide» en JavaScript

1494

Je voudrais faire la différence entre les objets de date valides et invalides dans JS, mais je n'ai pas pu comprendre 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 isValidDatefonction?

  • Ash est recommandé Date.parsepour l'analyse des chaînes de date, ce qui permet de vérifier si la chaîne de date est valide.
  • Ce que je préférerais, si possible, c'est que mon API accepte une instance de Date et puisse vérifier / affirmer si elle est valide ou non. La solution de Borgar le fait, mais je dois la tester sur tous les navigateurs. Je me demande également s'il existe une manière plus élégante.
  • Ash m'a fait envisager de ne pas avoir du tout d'acceptation d' Dateinstances par mon API , ce serait plus facile à valider.
  • Borgar a suggéré de tester une Dateinstance, puis de tester la Datevaleur de temps de. Si la date n'est pas valide, la valeur d'heure est NaN. J'ai vérifié avec ECMA-262 et ce comportement est dans la norme, c'est exactement ce que je recherche.
orip
la source
18
Vous pouvez supprimer l'instruction if en changeant le corps de la fonction en:return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
styfle
3
@styfle - devinez que c'est une préférence de style: je trouve plus clair de séparer la vérification de type de la logique d'égalité.
orip
26
Le discours @orip est exactement ce qui est fortement déconseillé dans les questions. Veuillez vous référer aux méta-sujets pertinents pour en connaître la justification. Placer une réponse à sa propre question dans la question elle-même est contraire à la politique du site. OTOH, remercier pour les réponses et avoir "EDIT" dans votre réponse est un fluff typique. Si vous voulez que votre question la mieux cotée vous identifie comme une personne qui ne sait pas ce qu'est le SO et comment l'utiliser, et ne souhaite pas l'apprendre - soyez mon invité.
14
@orip: Ce n'était pas "perdu"; il encombre toujours l'historique des révisions de la question si vous souhaitez la revoir. Mais cela n'a pas sa place dans une question. À 37k rep, vous devez savoir cela.
Courses de légèreté en orbite du
6
Veuillez arrêter la guerre d'édition. Les modifications sur cette question sont discutées sur la méta . Veuillez ne pas modifier / restaurer ce post plus loin. Si vous n'êtes pas d'accord avec les modifications / annulations précédentes ou si vous avez des commentaires à leur sujet, veuillez publier sur ce fil méta et non ici.
Lundin

Réponses:

1304

Voici comment je le ferais:

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 [31/05/2018] : Si vous n'êtes pas concerné par les objets Date 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);
}
Borgar
la source
21
instanceof se casse entre les trames. Le typage canard peut aussi très bien fonctionner: validDate == d && d.getTime &&! IsNaN (d.getTime ()); - Puisque la question concerne une fonction d'utilité générale, je préfère être plus stricte.
Borgar
11
@Borgar, je viens de trouver ma réponse: "Les problèmes se posent en ce qui concerne les scripts dans les environnements DOM multi-images. En résumé, les objets Array créés dans une iframe ne partagent pas les [[Prototype]] avec des tableaux créés dans une autre iframe . Leurs constructeurs sont des objets différents et donc les vérifications instanceof et constructeur échouent. "
Ash
64
vous n'avez même pas besoin d.getTimejusteisNan(d)
TecHunter
8
Pourrait être simplifié comme ceci:d instanceof Date && !isNaN(d.getTime())
Zorgatone
5
Merci pour la réponse, mais je tiens à souligner les commentaires de @Borgar et @blueprintChris: si j'analyse le chiffre 1par exemple, j'aurais toujours une date valide résultant Mon Jan 01 2001 00:00:00qui est en effet une date, mais pour les besoins de ma candidature, elle est complètement inutile . Ainsi, il y a un peu plus de validation d'entrée nécessaire dans mon cas au moins. Cette réponse valide un dateObjectpas un Date!
dnhyde
264

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 un horodatage, un entier représentant le nombre de millisecondes depuis 01 / Jan / 1970. Il retournera NaNs'il ne peut pas analyser la chaîne de date fournie.

Cendre
la source
119
-1 Je ne sais pas pourquoi cela a autant de votes positifs, Date.parsedépend de la mise en œuvre et n'est certainement pas fiable pour analyser les chaînes de date générales. Il n'y a pas de format unique qui soit correctement analysé dans les navigateurs populaires, encore moins tous ceux utilisés (bien que finalement le format ISO8601 spécifié dans ES5 devrait être correct).
RobG
1
Si vous utilisez le new Date('foo')c'est fondamentalement équivalent à la Date.parse('foo')méthode. Voir: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Donc ce que @RobG a dit, cela s'applique également à lui.
golddragon007
2
Ce test échouerait dans Chrome. Par exemple, Date.parse ('AAA-0001') dans Chrome me donne un nombre.
Nick
a échoué ... détecter toutes les valeurs numériques
Hos Mercury
109

Vous pouvez vérifier la validité d'un Dateobjet dvia

d instanceof Date && isFinite(d)

Pour éviter les problèmes de cross-frame, on pourrait remplacer le instanceofchèque par

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

Un appel à getTime()comme dans la réponse de Borgar est inutile car isNaN()et à la isFinite()fois convertir implicitement nombre.

Christoph
la source
Essayez ceci en chrome - Object.prototype.toString.call (nouvelle date ("2013-07-09T19: 07: 9Z")). Il renverra "[date d'objet]". Selon vous, par conséquent, "2013-07-09T19: 07: 9Z" devrait être une date valide. Mais ce n'est pas. Vous pouvez le vérifier, toujours en chrome, en faisant var dateStr = new Date ("2013-07-09T19: 07: 9Z"); dateStr Il renverra une date non valide.
Tintin
2
@Tintin: c'est pour ça isFinite()- toString.call()n'est qu'un remplacement pour la instanceofpartie du chèque
Christoph
La comparaison avec '[date d'objet]' fonctionnera-t-elle avec des navigateurs non anglais? J'en doute.
kristianp
2
@kristianp en fait, il le sera probablement et fait probablement partie de la spécification ECMAScript. Mais, oui, ça a l'air moche.
binki
Pour moi, la première approche ici est la meilleure option, bien que je ne sois pas sûr qu'il y ait un avantage réel à utiliser isFiniteover isNaN(les deux fonctionnent très bien avec Date(Infinity)). En outre, si vous voulez la condition d' en face, il devient un peu plus simple: if (!(date instanceof Date) || isNaN(date)).
Andrew
86

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

la mise en oeuvre

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();
};  

Usage

var d = new Date("lol");

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

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

console.log(d.isValid()); // true
Ash Clarke
la source
28
isNaNest un moyen plus explicite de tester NaN
orip
1
Et pourtant, vous trouvez toujours des gens qui écrivent leurs propres versions :) documentcloud.github.com/underscore/docs/…
Ash Clarke
4
puisque je respecte underscore.js, cela a suscité des recherches. isNaN("a") === true, tandis que ("a" !== "a") === false. Cela vaut la peine d'y penser. +1
orip
8
J'ai testé les performances des 3 principales solutions que j'ai trouvées ici. Félicitations, vous êtes le gagnant! jsperf.com/detecting-an-invalid-date
zVictor
2
@Ali C'est un objet date valide. new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time). Si vous passez une chaîne au constructeur de date, vous devez passer une chaîne standardisée pour obtenir un résultat fiable. Plus précisément, «La chaîne doit être dans un format reconnu par la méthode Date.parse ()». developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ash Clarke
71

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

if(!isNaN(date.getTime()))
abhirathore2006
la source
2
Le seul problème est que si la date n'est pas de type Date; vous obtenez une erreur JS.
Andrew
@Andrew, vous devez créer l'objet date et si vous avez déjà un objet, utilisezdate && !isNaN(date.getTime())
abhirathore2006
Cela vous donne toujours une erreur JS si elle daten'est pas de type Date. Par exemple: var date = 4; date && !isNaN(date.getTime());.
Andrew
@Andrew use date instanceof Date && !isNaN(date.getTime())
abhirathore2006
3
D'accord, comme les autres réponses d'il y a 8 ans. : P stackoverflow.com/a/1353945/2321042
Andrew
45

Vous pouvez simplement utiliser moment.js

Voici un exemple:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

La section de validation de la documentation est assez claire.

Et aussi, les indicateurs d'analyse suivants entraînent une date non valide:

  • overflow: Un débordement d'un champ de date, tel qu'un 13e mois, un 32e jour du mois (ou le 29 février les années non bissextiles), un 367e jour de l'année, etc. le débordement contient l'index de l'unité non valide pour correspondre à #invalidAt (voir ci-dessous); -1 signifie pas de débordement.
  • invalidMonth: Un nom de mois non valide, tel que moment ('Marbruary', 'MMMM') ;. Contient la chaîne de mois non valide elle-même, ou bien null.
  • empty: Une chaîne d'entrée qui ne contient rien d'analysable, comme moment ('c'est absurde') ;. Booléen.
  • Etc.

Source: http://momentjs.com/docs/

Yves M.
la source
6
La meilleure solution, extrêmement facile à implémenter, fonctionne avec n'importe quel format (mon cas est jj / MM / aaaa), connaît également les années bissextiles et ne convertit pas les dates invalides (par exemple 29/02/2015) en elles-mêmes valides (par exemple 30/03/2015). Pour vérifier une date dans le format jj / mm / aaaa que je viens d'avoir à utilisermoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin
3
Cette utilisation de Moment est déconseillée :(
James Sumners
2
Cette utilisation n'a pas été dépréciée. Le moment d'appel (entrée) sans chaîne de format est amorti (sauf si l'entrée est au format ISO).
Chet
2
Cette méthode peut être extrêmement lente lors du traitement de nombreuses dates. Mieux vaut utiliser une expression régulière dans ces cas.
Grid Trekkor
2
L'utilisation de moment.js peut être simple, mais représente une énorme surcharge. Cette bibliothèque est ÉNORME. J'ai rétrogradé votre réponse.
Mick
38

Je voudrais mentionner que le widget jQuery UI DatePicker a une très bonne méthode utilitaire de validation de date qui vérifie le format et la validité (par exemple, aucune date 01/33/2013 n'est autorisée).

Même si vous ne souhaitez pas utiliser le widget datepicker sur votre page en tant qu'élément d'interface utilisateur, vous pouvez toujours ajouter sa bibliothèque .js à votre page, puis appeler la méthode validator, en lui transmettant la valeur que vous souhaitez valider. Pour rendre la vie encore plus facile, il faut une chaîne en entrée, pas un objet Date JavaScript.

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

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

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

Exemple d'utilisation:

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.';
}

(Plus d'informations sur la spécification des formats de date se trouvent sur http://api.jqueryui.com/datepicker/#utility-parseDate )

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

Si une valeur de chaîne transmise est correctement analysée, la valeur de 'testdate' serait un objet Javascript Date représentant la valeur de chaîne transmise. Sinon, ce ne serait pas défini.

Matt Campbell
la source
3
Upvote pour être la première réponse à travailler avec des formats de date non anglais / locaux.
hache.
26

J'ai vraiment aimé l'approche de Christoph (mais je n'avais pas assez de réputation pour voter). Pour mon usage, je sais que j'aurai toujours un objet Date, donc je viens de prolonger la date avec une méthode valid ().

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

Maintenant, je peux simplement écrire ceci et c'est beaucoup plus descriptif que de simplement vérifier isFinite dans le code ...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
broox
la source
10
Extension du prototype? C'est un gros JavaScript non non!
Jasdeep Khalsa
Voter en raison du isFinitetravail pour moi parfaitement. Mais oui, inutile d'étendre le prototype. !isFinitesur un Dateattraper le fait que l' Dateest Invalid Date. Il convient également de noter que mon contexte est à l'intérieur de Node.
Staghouse
23
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
faridz
la source
5
C'est la même que @Borgar a écrit il y a 2 ans ... Quoi de neuf ??
bleuâtre à
11
Il s'agit de deux lignes au lieu de vilaines instructions if imbriquées.
Cypher
17

vous pouvez vérifier le format valide de txDate.value avec ce scirpt. s'il était dans un format incorrect, la date n'est pas instanciée et renvoie null à dt.

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

Et comme l'a suggéré @ MiF en bref

 if(isNaN(new Date(...)))
Yuseferi
la source
isNaN (new Date (...)) - la méthode simple et courte
MiF
1
@MiF oui, je mets à jour ma réponse avec votre suggestion;) merci
Yuseferi
16

J'utilise le code suivant pour valider les valeurs de l'année, du mois et de 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, reportez-vous à Vérifier la date en javascript

Jingguo Yao
la source
strn'est pas utilisé.
samis
12

Trop de réponses compliquées ici déjà, mais une simple ligne suffit (ES5):

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

ou même dans ES6:

Date.prototype.isValid = d => !isNaN(Date.parse(d));
Sebastien H.
la source
1
De MDN: "La méthode Date.parse () analyse une représentation sous forme de chaîne d'une date, et retourne le nombre de millisecondes depuis le 1er janvier 1970, 00:00:00 UTC ou NaN ..." Donc, l'exécution d'une date potentielle à travers cette La fonction renvoie soit un entier soit NaN. Ensuite, la fonction isNaN () donnera un booléen propre vous indiquant si la valeur d'origine était un objet date valide ou non. Cela suffit pour effectuer une vérification ponctuelle, mais l'exemple ci-dessus associe ensuite cette méthode à l'objet Date pour rendre la fonctionnalité facilement disponible et lisible dans tout votre programme.
Max Wilder
si d est booléen vous recevrez 0 ou 1 qui n'est pas un Nan !!
davcup
@davcup vient d'être testé en utilisant Date.parse(true), j'obtiens correctement un NaN.
Sebastien H.
12

J'ai vu des réponses très proches de ce petit extrait.

Manière JavaScript:

function isValidDate(dateObject){ return new Date(dateObject).toString() !== 'Invalid Date'; }
isValidDate(new Date('WTH'));

Manière TypeScript:

const isValidDate = dateObject => new Date(dateObject ).toString() !== 'Invalid Date';
isValidDate(new Date('WTH'));
Jason Foglia
la source
1
Vous ne savez pas si je manque quelque chose, mais je ne fais pas deux fois Date () inutile?
Jon Catmull
2
Ce dernier n'a rien à voir avec TypeScript. C'est JS parfaitement valide.
hackel
9

Bonne solution! Inclus dans ma bibliothèque de fonctions auxiliaires, il ressemble maintenant à 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());
}
Dmytro Shevchenko
la source
9

Cela a juste fonctionné pour moi

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

Mais cela n'a pas fonctionné

new Date('foo') === 'Invalid Date'; //is false
user1296274
la source
5
Je pense que cela dépend du navigateur.
barrypicker
@barrypicker Que voulez-vous dire par le fait que cela dépend du navigateur?
Ajil O.
Vous pouvez faire: `${new Date('foo')}` === 'Invalid Date'
Daniele Vrut
9

Pour les projets Angular.js, vous pouvez utiliser:

angular.isDate(myDate);
Nick Taras
la source
3
Cela renvoie true pour le test d'un objet date qui a été initialisé avec une date non valide.
dchhetri
6

Aucune de ces réponses n'a fonctionné pour moi (testée dans Safari 6.0) lorsque vous essayez de valider une date telle que le 31/02/2012, cependant, elles fonctionnent correctement lorsque vous essayez une date supérieure à 31.

J'ai donc dû faire un peu de force brute. En supposant que la date est au format mm/dd/yyyy. J'utilise @broox answer:

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
Dex
la source
(nouvelle date ('30/02/2014')). valid () renvoie vrai
Andre Figueiredo
1
Cela fait un moment que je n'ai pas répondu, mais vous devrez peut-être les deux conditions de retour, y compris le&& value.split('/')[0] == (d.getMonth()+1);
Dex
L'utilisation new Date('string date')est équivalente à Date.parse('string date'), voir: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… afin que vous puissiez obtenir de fausses valeurs vraies ou fausses.
golddragon007
5

Aucune des solutions ci-dessus n'a fonctionné pour moi.

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 fera le 31/02/2012 au 03/02/2012 que ce n'est pas valide

John
la source
3
D'accord, mais cela teste si une chaîne est une date au format M / D / Y, pas "la différence entre des objets de date valides et invalides". Ce n'est pas vraiment de quoi il s'agit.
Borgar
la raison pour laquelle sa vérification par rapport au format est de vérifier si la date a changé après avoir été analysée
John
L'OP ne demande-t-il pas une méthode pour renvoyer un booléen, pas une chaîne formatée?
barrypicker
1
L'exemple de code renvoie un booléen, le formatage joue un rôle dans les tests de certains cas non valides.
John
5
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;
}
Michael Goldshmidt
la source
4

J'ai écrit cette fonction. Passez-lui un paramètre de chaîne 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: false.

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

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

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;
    }
}
Yaseen
la source
4

Date.prototype.toISOStringjette RangeError(au moins dans Chromium et Firefox) à des dates invalides. Vous pouvez l'utiliser comme moyen de validation et ne pas avoir besoin en isValidDatetant que tel (EAFP). Sinon c'est:

function isValidDate(d)
{
  try
  {
    d.toISOString();
    return true;
  }
  catch(ex)
  {
    return false;    
  }    
}
saaj
la source
1
Il semble que ce soit la seule fonction qui génère une erreur par définition ECMA-262. 15.9.5.43 Date.prototype.toISOString () Cette fonction renvoie une valeur String représentant l'instance dans le temps représentée par cet objet Date. Le format de la chaîne est le format de chaîne date-heure défini au 15.9.1.15. Tous les champs sont présents dans la chaîne. Le fuseau horaire est toujours UTC, indiqué par le suffixe Z. Si la valeur de temps de cet objet n'est pas un nombre fini, une exception RangeError est levée.
Henry Liu
3

Inspiré par l'approche de Borgar, je me suis assuré que le code non seulement valide la date, mais s'assure en fait que la date est une date réelle, ce qui signifie que des dates comme 31/09/2011 et 29/02/2011 ne sont pas autorisées.

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!";
}
Raz
la source
Mais ... les méthodes ci-dessus (@ Borgar's et les autres) vérifient déjà ce type de validité ... Je ne peux pas obtenir le problème.
bleuâtre
Borgar ne le voit pas - voir son propre commentaire à sa réponse.
EML
1
Cette solution ne fonctionne que lorsque votre pays utilise la dd/MM/yyyynotation. De plus, il retourne truelorsqu'il est valide et 'Invalid date!'si ce n'est pas le cas, il vaut mieux ne renvoyer qu'un seul type.
A1rPun
3

J'ai combiné les meilleurs résultats de performance que j'ai trouvés autour de cette 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;
};
zVictor
la source
2

L'objet date à chaîne est un moyen plus simple et plus fiable de détecter si les deux champs sont une date valide. Par exemple, si vous entrez ce "-------" dans le champ de saisie de la date. Certaines des réponses ci-dessus ne fonctionneront 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}.');
kam
la source
2

La réponse choisie est excellente et je l'utilise également. Cependant, si vous cherchez un moyen de valider la saisie de la date de l'utilisateur, vous devez savoir que l'objet Date est très persistant pour transformer ce qui peut sembler être des arguments de construction non valides en arguments valides. Le code de test 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());
});
dolphus333
la source
2
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
kiranvj
la source
2

Une fonction prête basée sur la réponse la mieux notée:

  /**
   * 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;
}
Zon
la source
2

Solution simple et élégante:

const date = new Date(`${year}-${month}-${day} 00:00`)
const isValidDate = (Boolean(+date) && date.getDate() == day)

sources:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] Date incorrecte affichée dans la nouvelle date () en JavaScript

Sobriquet
la source
1
date.getDate() == dayest insuffisant pour déterminer si la date est valide. Le format de date d'origine renverra une date non valide dans certaines implémentations, que la date soit valide ou non. "1970-01-01 00:00", si analysé correctement, renvoie false (c'est-à-dire Boolean(+new Date("1970-01-01"))renvoie false).
RobG
AVERTISSEMENT: cela ne fonctionnera pas dans Safari
Vigrant
Cela fonctionnera dans Safari si vous utilisez le format const date = new Date(year, month, day); Notez que le mois est 0 indexé de cette façon, vous devrez donc en soustraire un pour l'aligner correctement.
Vigrant le
1

Je pense qu'une partie de ce processus est long. Nous pouvons le raccourcir comme indiqué 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;
    }
user889209
la source
3
La question demandait comment trouver des instances de date invalides, pas des chaînes, et en plus: qui dit qu'une date ne peut pas être délimitée par autre chose qu'une barre oblique?
Jon z
1

Pour les composants basés sur 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
};

Tests:

    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)
Denis Ryzhkov
la source