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 deDate
. Si la date n'est pas valide, la valeur temporelle estNaN
. Je vérifié avec ECMA-262 et ce comportement est dans la norme, qui est exactement ce que je cherche.
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);
}
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.
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.
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
réponse la plus courte pour vérifier la date de validité
if(!isNaN(date.getTime()))
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 très claire.
et aussi, les options d'analyse suivantes entraînent une date invalide:
-
overflow
: un débordement d'un champ de date, tel qu'un 13e mois, un 32e jour du mois (ou un 29 février pour les années non bissextiles), un 367e jour de l'année, etc. overflow contient l'index de l'unité invalide pour correspondre à #invalidAt (voir ci-dessous); -1 signifie pas de overflow. -
invalidMonth
: un nom de mois invalide, tel que moment('Marbruary', 'MMMM');. Contient la chaîne de caractères invalide elle-même, ou bien null. -
empty
: une chaîne de caractères d'entrée qui ne contient rien de parsable, comme le moment('This is nonsense');. Booléen. - etc.
Source: http://momentjs.com/docs /
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.
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 */ }
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
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
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));
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(...)))
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());
}
Pour Angulaire.vous pouvez utiliser les projets js:
angular.isDate(myDate);
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
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
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;
}
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
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;
}
}
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!";
}
j'ai combiné les meilleurs résultats que j'ai trouvé autour de la vérification si un objet donné:
- est une instance de Date ( référence ici )
- a une date valide ( référence ici )
Le résultat est le suivant:
function isValidDate(input) {
if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
return false;
var time = input.getTime();
return time === time;
};
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}.');
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';
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());
});
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
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;
}
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;
}
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)
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.
function isValidDate(date) {
return !! (Object.prototype.toString.call(date) === "[object Date]" && +date);
}