Vérifiez si une chaîne est une valeur de date

207

Quel est un moyen simple de vérifier si une valeur est une date valide, n'importe quel format de date connu autorisé.

Par exemple , j'ai les valeurs 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000qui devraient tous être reconnus comme des valeurs de date, et les valeurs 200, 10, 350qui ne doivent pas être considérés comme une valeur de date. Quelle est la manière la plus simple de vérifier cela, si cela est même possible? Parce que les horodatages seraient également autorisés.

Thizzer
la source

Réponses:

41

Cela Date.parse()suffirait?

Voir sa page relative à la documentation MDN .

Asmor
la source
24
Soyez prudent avec cela car il renverra toujours un retour pour des dates non valides en février, par exemple: 2013-02-31
leojh
58
Une autre raison de faire attention - les chiffres analysent les dates. Date.parse("4.3")est 986270400000.
Mogsdad
J'ai essayé un violon avec les deux cas de «prudence» ci-dessus: console.log (Date.parse («2013-02-31»)); console.log (Date.parse ("4.3")); et dans les deux cas (sur Firefox), il a retourné NaN, donc pour moi, Date.parse semble OK (je prévaut pour les tirets et la longueur correcte avant l'analyse de toute façon).
Cloudranger
55
Désolé @Asmor, ce n'est pas une bonne réponse. Date.parse analysera n'importe quelle chaîne avec un nombre.
jwerre
11
Date.parse ("My Name 8") arrive comme 99662040000, ce qui est faux. J'ai utilisé ça et maintenant je souffre.
Rohith
250

Mise à jour 2015

C'est une vieille question mais d'autres nouvelles questions comme:

être fermé en double de celui-ci, donc je pense qu'il est important d'ajouter de nouvelles informations ici. Je l'écris parce que j'ai eu peur de penser que les gens copient et collent une partie du code affiché ici et l'utilisent en production.

La plupart des réponses ici utilisent soit des expressions régulières complexes qui ne correspondent qu'à certains formats très spécifiques et le font en fait de manière incorrecte (comme la correspondance du 32 janvier sans correspondance avec la date ISO réelle comme annoncé - voir la démo ), soit elles essaient de transmettre quoi que ce soit au Dateconstructeur et souhaite le meilleur.

Utiliser Moment

Comme je l'ai expliqué dans cette réponse, il existe actuellement une bibliothèque disponible pour cela: Moment.js

Il s'agit d'une bibliothèque pour analyser, valider, manipuler et afficher les dates en JavaScript, qui possède une API beaucoup plus riche que les fonctions de gestion de date JavaScript standard.

Il est réduit à 12 Ko / gzippé et fonctionne dans Node.js et d'autres endroits:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

En utilisant Moment, vous pouvez être très précis sur la vérification des dates valides. Parfois, il est très important d'ajouter quelques indices sur le format que vous attendez. Par exemple, une date telle que 22/06/2015 ressemble à une date valide, sauf si vous utilisez un format JJ / MM / AAAA, auquel cas cette date doit être rejetée comme non valide. Il existe plusieurs façons de dire à Moment à quel format vous vous attendez, par exemple:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

L' trueargument est là, donc le Moment n'essaiera pas d'analyser l'entrée si elle n'est pas exactement conforme à l'un des formats fournis (ce devrait être un comportement par défaut à mon avis).

Vous pouvez utiliser un format fourni en interne:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

Et vous pouvez utiliser plusieurs formats en tant que tableau:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

Voir: DEMO .

Autres bibliothèques

Si vous ne souhaitez pas utiliser Moment.js, il existe également d'autres bibliothèques:

Mise à jour 2016

J'ai créé le module immoment qui est comme (un sous-ensemble de) Moment mais sans surprise causé par la mutation d'objets existants (voir la documentation pour plus d'informations).

Mise à jour 2018

Aujourd'hui, je recommande d'utiliser Luxon pour la manipulation de date / heure au lieu de Moment, ce qui (contrairement à Moment) rend tous les objets immuables donc il n'y a pas de mauvaises surprises liées à la mutation implicite des dates.

Plus d'informations

Voir également:

Une série d'articles de Rob Gravelle sur les bibliothèques d'analyse de dates JavaScript:

Conclusion

Bien sûr, n'importe qui peut essayer de réinventer la roue, écrire une expression régulière (mais veuillez lire ISO 8601 et RFC 3339 avant de le faire) ou appeler des constructeurs intégrés avec des données aléatoires pour analyser les messages d'erreur comme 'Invalid Date'(Êtes-vous sûr que ce message est exactement la même sur toutes les plates-formes? Dans tous les pays? À l'avenir?) ou vous pouvez utiliser une solution testée et utiliser votre temps pour l'améliorer, pas la réinventer. Toutes les bibliothèques répertoriées ici sont des logiciels libres et open source.

rsp
la source
4
comment utiliser exactement cela? moment("whatever 123").isValid()retourne true.
krivar
4
@krivar Il est préférable de l'utiliser comme ceci: moment("06/22/2015", "DD/MM/YYYY", true).isValid();avec le format de date attendu explicitement fourni et avec un argument truesignifiant une vérification stricte. J'ai mis à jour ma réponse avec plus d'informations et de meilleurs exemples.
rsp
2
Même si, mais je valider l' entrée d'utilisateur et je ne sais pas le format de date prévue ...
Jan Van der Haegen
3
@JanVanderHaegen Si l'on peut supposer que 3/4/5 est une date valide, tout comme le 1er avril 2015, je recommanderais d'ajouter ces formats (et potentiellement beaucoup plus) à une liste explicite de formats pris en charge. Notez que 3/4/5 que vous avez mentionné est ambigu sans un format explicite.
rsp
3
Cela pourrait être la réponse la meilleure et la mieux entretenue que j'ai vue sur SO
Phil3992
63

Voici comment j'ai résolu ce problème dans une application sur laquelle je travaille en ce moment:

mis à jour sur la base des commentaires de krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Neil Girardi
la source
5
J'avais besoin de retourner (nouvelle date (date)). ToString ()! == "Date invalide" pour le nœud. Notez également cela? vrai: faux est redondant. il suffit de renvoyer l'expression ici.
domenukk
Dans IE8, new Date(date)ne vous donne pas de «date non valide».
krillgar
13
Ce n'est pas une bonne réponse. new Date(date) !== "Invalid Date"sera toujours revenir vrai puisque l'expression gauche renverra un objet Date avec un TEMPSVAL de NaN , qui ne peut jamais être ===une chaîne. Utilisation de =="travaux" en raison de la conversion de type. Mais comme l'analyse des chaînes de date dépend encore largement de l'implémentation, s'appuyer sur elle pour analyser des formats aléatoires nous a sérieusement faussés.
RobG
4
la nouvelle date ("469") entraîne le mar. 01 janvier 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana
3
Ceci est similaire à la bonne réponse faussement acceptée. isDate('Mac OS X 10.14.2')renvoie vrai ici.
BradStell
24

new Date(date) === 'Invalid Date'ne fonctionne que dans Firefox et Chrome. IE8 (celui que j'ai sur ma machine à des fins de test) donne NaN.

Comme indiqué dans la réponse acceptée, Date.parse(date)fonctionnera également pour les chiffres. Donc, pour contourner cela, vous pouvez également vérifier qu'il ne s'agit pas d'un nombre (si c'est quelque chose que vous souhaitez confirmer).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}
krillgar
la source
2
Je me rends compte que c'est quelques années plus tard, mais ce isNann'est pas une fonction; cas incorrect en première instance.
Tim Lewis
Ne marche pas. Si datec'est le cas Foostreet 1, votre condition est évaluée comme vraie.
Fabian Picone
9

Que diriez-vous quelque chose comme ça? Il testera s'il s'agit d'un objet Date ou d'une chaîne de date:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Je dois mentionner que cela ne teste pas les chaînes au format ISO, mais avec un peu plus de travail sur RegExp, vous devriez être bon.

jwerre
la source
7

Aucune des réponses ici ne permet de vérifier si la date n'est pas valide, comme le 31 février. Cette fonction corrige cela en vérifiant si le mois retourné est équivalent au mois d'origine et en s'assurant qu'une année valide a été présentée.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 
ykay dit Réintégrer Monica
la source
Parce que la question n'est pas de savoir si une chaîne est une date «valide», mais simplement de vérifier si une chaîne représente un format de date.
Thizzer
@Thizzer bon point. Cela ne me dérangerait pas de corriger, mais en relisant votre question, je suis perplexe parce que vous dites que 10 ne devrait pas être validé mais que les horodatages devraient être autorisés.
ykay dit Réintégrer Monica
xD n'a même pas remarqué cela, une question de mes premiers jours avec date / horodatage. Je vais essayer de modifier la question plus tard dans la journée.
Thizzer
pourquoi mois-1 puis mois + 1?
Kapil Raghuwanshi
Les dates javascript de @KapilRaghuwanshi utilisent un mois de base zéro, vous devez donc soustraire 1 pour créer la date correcte et ajouter 1 pour vérifier si elle est équivalente au mois d'origine
ykay dit Reinstate Monica
5

Utilisez l'expression régulière pour le valider.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }
lpradhap
la source
4

En me référant à tous les commentaires ci-dessus, je suis parvenu à une solution.

Cela fonctionne si le Datepassé est au format ISO ou doit être manipulé pour d'autres formats.

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

Vous pouvez jouer ici sur JSFiddle.

Nikhil Zurunge
la source
1
Cette solution a fonctionné le mieux pour moi car les chaînes de date prises en charge par mon application sont au format YYYY-MM-DD, il est donc trivial de joindre T00:00:00.000Zet d'utiliser cette solution pour vérifier les chaînes valides.
accélérer
pour javascript, cela fonctionne, mais comment l'utiliser en tapuscrit.?
Sae
3

Voici une fonction améliorée qui utilise uniquement Date.parse():

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

Remarque: Date.parse () analysera les nombres: par exemple Date.parse(1), renverra une date. Nous vérifions donc ici si ce sn'est pas un nombre, si c'est une date.

A-Sharabiani
la source
1
cela ne fonctionne pas car passer le «test 2» passera comme une vraie date. testé dans la dernière version de chrome
user1751287
2

Je ferais ça

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Jouez ici

kiranvj
la source
2
Cela ne fonctionne pas dans Chrome actuel, probablement dans d'autres navigateurs. J'ai changé la chaîne fournie EXAMPLE STRING 12345et elle renvoie "date valide".
1

Voici une version minimaliste.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
M. Polywhirl
la source
1
Ne fonctionne toujours pas pour mon exemple:isDate("  1")
Tomas
@Tom Vous devez vérifier si la valeur contient des caractères blancs avant de déterminer s'il s'agit d'une date. Votre problème est un cas spécial qui doit être géré par la logique de votre contrôleur.
M. Polywhirl
1
La vérification des caractères d'espace blanc ne devrait pas être requise car la chaîne 1 janvier 2020 est une date valide qui contient un espace blanc. Votre méthode n'en tient pas compte.
Kirstin Walsh
1

Cette fonction appelable fonctionne parfaitement, renvoie true pour une date valide. Assurez-vous d'appeler en utilisant une date au format ISO (aaaa-mm-jj ou aaaa / mm / jj):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}
Peter DK
la source
1
C'est bien, mais cela ne répond pas complètement à la question. Plus précisément, cela ne fonctionne pas pour '2009-11-10T07: 00: 00 + 0000', l'un des exemples donnés.
amadan
Ne pensez pas que cela fonctionne comme il se doit validateDate ('2016-12-30T08: 00: 00.000Z') // false
Jose Browne
Que cela fonctionne ou non, cela pourrait être simplifié commereturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung
1

Je sais que c'est une vieille question, mais j'ai fait face au même problème et j'ai vu qu'aucune des réponses ne fonctionnait correctement - en particulier en éliminant les nombres (1 200 345, etc.) des dates, ce qui est la question d'origine. Voici une méthode plutôt peu orthodoxe à laquelle je pourrais penser et elle semble fonctionner. Veuillez indiquer s'il y a des cas où cela échouera.

if(sDate.toString() == parseInt(sDate).toString()) return false;

C'est la ligne pour éliminer les chiffres. Ainsi, la fonction entière pourrait ressembler à:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));

peekolo
la source
1
console.log("hello 1 ", isDate("hello 1 "));retourne vrai
John
vous avez raison! avez-vous une solution? Jusqu'à présent, je pense qu'aucune des réponses ici n'a vraiment abordé la question de manière appropriée!
peekolo
"100%", un pourcentage, renvoie vrai
toddmo
0

est-il correct de vérifier si une fonction liée à la date est disponible pour que l'objet trouve s'il s'agit d'un objet Date ou non?

comme

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;
Kishore Relangi
la source
0

C'est ainsi que je finis par le faire. Cela ne couvrira pas tous les formats. Vous devez vous ajuster en conséquence. Je contrôle le format, donc ça marche pour moi

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }
kheya
la source
-1

Ok, c'est une vieille question, mais j'ai trouvé une autre solution en vérifiant les solutions ici. Pour moi, cela fonctionne pour vérifier si la fonction getTime () est présente dans l'objet date:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
m.steini
la source
-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

Une bibliothèque légère est prête pour vous: Day.js

Nokey
la source
1
Il s'agit essentiellement de publicité sur StackOverflow, abstenez-vous de le faire.
c4sh
-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Par défaut, ce paramètre est défini sur TRUE. Ainsi, même les chaînes de format incorrect renvoient de bonnes valeurs.

Je l'ai utilisé quelque chose comme ça:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }
Anupam Mahapatra
la source
5
... javascript?!
artparks
-5

Essaye ça:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}
Andrew Hare
la source
6
Cela ne fonctionne pas pour moi. D'abord, la var dans la condition n'analyse pas, mais si vous supprimez cela et essayez quelque chose comme ceci: if (date = new Date ("ordures"))) {alert (date); } Même si la date est une ordure, l'alerte sera toujours exécutée car la fonction Date renverra "Date non valide" (sur firefox au moins) de sorte que la condition est évaluée comme vraie. Je suppose que si certains navigateurs renvoient null à une date non valide, cela fonctionnerait sur ces navigateurs. Il pourrait y avoir une incohérence du navigateur ici.
Cloudranger