web-dev-qa-db-fra.com

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

Quel est un moyen facile de vérifier si une valeur est une date valide, tout format de date connu autorisé.

Par exemple, j'ai les valeurs 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000 qui doivent toutes être reconnues comme des valeurs de date et les valeurs 200, 10, 350, qui ne doit pas être reconnu comme une valeur de date. Quel est le moyen le plus simple de vérifier cela, si cela est même possible? Parce que les horodatages seraient également autorisés.

173
Thys

Date.parse() suffirait-il?

Voir son relatif page Documentation MDN .

41
Asmor

Mise à jour 2015

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

devenez des doublons de celui-ci, alors 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 pour la production.

La plupart des réponses ici utilisent des expressions régulières complexes qui ne correspondent qu'à des formats très spécifiques et le font en fait de manière incorrecte (comme faire correspondre le 32 janvier sans correspondre à la date ISO réelle annoncée - voir demo ) ou ils essaient de passer quoi que ce soit au constructeur Date et souhaitent le meilleur.

Utiliser le moment

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

Il s'agit d'une bibliothèque pour analyser, valider, manipuler et afficher les dates en JavaScript, dotée d'une API beaucoup plus riche que les fonctions standard de traitement des dates par JavaScript.

Il est 12kB minified/gzipped et fonctionne dans Node.js et d’autres lieux:

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. Il est parfois très important d’ajouter des indices sur le format que vous attendez. Par exemple, une date telle que 06/22/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 le format auquel 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'argument true existe pour que le moment ne tente pas d'analyser l'entrée si elle ne n'est pas exactement conforme à l'un des les 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: DÉMO .

Autres bibliothèques

Si vous ne voulez pas utiliser Moment.js, il existe aussi d'autres bibliothèques:

Mise à jour 2016

J'ai créé le module immoment qui ressemble à (un sous-ensemble de) Moment mais sans surprises causées 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 la date/heure au lieu de Moment, qui (contrairement à Moment) rend tous les objets immuables, évitant ainsi toute mauvaise surprise liée à 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 date JavaScript:

Ligne de fond

Bien sûr, n'importe qui peut essayer de réinventer la roue, d'écrire une expression régulière (mais s'il vous plaît lisez réellement ISO 8601 et RFC 3339 avant de le faire) ou appelez des constructeurs avec des données aléatoires. analyser les messages d'erreur tels que 'Invalid Date' (Etes-vous sûr que ce message est exactement identique sur toutes les plateformes? Dans toutes les langues? À l'avenir?) ou vous pouvez utiliser une solution testée et utiliser votre temps pour l’améliorer, pas pour la réinventer. Toutes les bibliothèques répertoriées ici sont des logiciels libres à code source ouvert.

212
rsp

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

mis à jour en fonction des commentaires de krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

ou ...

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date" && !isNaN(new Date(date)) ) ? true : false;
}

....

58
Neil Girardi

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 nombres. Donc, pour contourner cela, vous pouvez également vérifier que ce n'est pas un nombre (si c'est quelque chose que vous voulez 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 */
}
21
krillgar

Que diriez-vous quelque chose comme ça? Il vérifiera 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 devrais mentionner que cela ne teste pas les chaînes au format ISO, mais avec un peu plus de travail pour RegExp, vous devriez être bon.

8
jwerre

Aucune des réponses ici ne vérifie si la date est invalide, telle que le 31 février. Cette fonction permet de vérifier si le mois renvoyé est équivalent au mois initial et de s’assurer qu’une année valide a bien é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];
} 
7
ykay

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);
    }
4
lpradhap

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

Cela fonctionne si la date passée est au format ISO ou doit être manipulée 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

4
Nikhil Zurunge

Je ferais ça

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

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

Jouer ici

3
kiranvj

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 éliminant spécifiquement les nombres (1 200 345, etc.) des dates, ce qui est la question initiale. Voici une méthode peu orthodoxe à laquelle je pouvais penser et qui 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 nombres. 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"));
2
peekolo

Voici une version minimaliste.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
2
Mr. Polywhirl

La date peut être validée en utilisant la réponse suivante

 var year=2019;
 var month=2;
 var date=31;
 var d = new Date(year, month - 1, date);
 if (d.getFullYear() != year
    || d.getMonth() != (month - 1)
    || d.getDate() != date) {
alert("invalid date");
return false;
}
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;
}
1
Peter DK

Après avoir essayé toutes les réponses énumérées ci-dessus, je me suis retrouvé avec ce qui suit:

var checkDateValue = function(date) {
    return date && (!(new Date(date) == "Invalid Date") && !isNaN(new Date(date)));
};

Notez que new Date(date) !== "Invalid Date" est toujours vrai. J'espère que cela t'aides.

0
dyatchenko

C'est comme ça que je finis par le faire. Cela ne couvrira pas tous les formats. Vous devez vous adapter en conséquence. J'ai le contrôle sur 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;
            }
        }
0
kheya

Essaye ça

<input type="text" id="StartDay" value="2018/01/01" maxlength="10" />

$('#StartDay').change(function () {
    if ( ($('#StartDay').val().length == 10 && new Date($('#StartDay').val()) >= new Date("2018/01/01") &&
        (new Date($('#StartDay').val()) !== "Invalid Date") && !isNaN(new Date($('#StartDay').val()))) == false) {
     .....
    }
})
0
Willie Cheng

Vérifier les données ISO (manière fonctionnelle ES6)

const isISODate = date => 
  new Date(date) !== "Invalid Date" 
  && !isNaN(new Date(date)) 
  && date == new Date(date).toISOString();

console.log(
   isISODate("2018-08-01T18:30:00.000Z")
);

Une ligne

const isISODate = date => new Date(date) !== "Invalid Date" && !isNaN(new Date(date)) && date == new Date(date).toISOString();

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

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
0
m.steini

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

comme

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