сравнение - Обнаружение экземпляра даты «недействительной даты» в JavaScript
сравнение дат js (20)
Вы можете просто использовать moment.js
Вот пример:
var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false
Раздел проверки в документации достаточно ясен.
Кроме того, следующие флаги разбора приводят к недопустимой дате:
-
overflow
: переполнение поля даты, например, 13-й месяц, 32-й день месяца (или 29 февраля в непиковые годы), 367-й день года и т. д. переполнение содержит индекс недействительного единица соответствует #invalidAt (см. ниже); -1 означает отсутствие переполнения. -
invalidMonth
: Недействительное имя месяца, например, момент ('Marbruary', 'MMMM') ;. Содержит недействительную строку месяца, а также значение null. -
empty
: входная строка, которая не содержит ничего разборного, например момент («это вздор») ;. Boolean. - И т.п.
Источник: http://momentjs.com/docs/
Я хотел бы рассказать разницу между действительными и недопустимыми объектами даты в JS, но не мог понять, как:
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'
Любые идеи для написания функции isValidDate
?
- Пепел рекомендовал
Date.parse
для синтаксического анализа строк даты, что дает авторитетный способ проверить правильность строки даты. - Я бы предпочел, если это возможно, заставить мой API принять экземпляр Date и проверить / подтвердить, является ли он действительным или нет. Решение Borgar делает это, но мне нужно проверить его в браузерах. Я также задаюсь вопросом, есть ли более элегантный способ.
- Эш заставил меня подумать о том, что мой API не принимает экземпляры
Date
вообще, это было бы проще всего проверить. - Боргар предложил провести тестирование экземпляра
Date
, а затем проверить значение времениDate
. Если дата недействительна, значением времени являетсяNaN
. Я проверил с ECMA-262 и это поведение находится в стандарте, и это именно то, что я ищу.
Вдохновленный подходом Боргара, я убедился, что код не только проверяет дату, но фактически гарантирует, что дата является реальной датой, что означает, что даты 31/09/2011 и 29/02/2011 не допускаются.
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!";
}
Вот как я это сделаю:
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
}
Update [2018-05-31] : Если вы не связаны с объектами Date из других контекстов JS (внешние окна, фреймы или фреймы), эта более простая форма может быть предпочтительной:
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
Вы можете проверить действительность объекта Date
d
через
d instanceof Date && isFinite(d)
Чтобы избежать проблем с несколькими кадрами, можно заменить проверку instanceof
Object.prototype.toString.call(d) === '[object Date]'
Вызов getTime()
как и в ответе Боргара, не нужен, как isNaN()
и isFinite()
и неявно преобразуется в число.
Готовая функция, основанная на наивысшем рейтинге:
/**
* 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;
}
Для компонент на основе 1-й даты:
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
};
тесты:
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)
Как правило, я придерживаюсь того, что имплантация Date находится в стеке браузера. Это означает, что вы всегда будете получать «Недействительную дату» при вызове toDateString () в Chrome, Firefox и Safari с даты этого ответа.
if(!Date.prototype.isValidDate){
Date.prototype.isValidDate = function(){
return this.toDateString().toLowerCase().lastIndexOf('invalid') == -1;
};
}
Однако я не тестировал это в IE.
Мне очень понравился подход Кристофа (но не хватило репутации, чтобы его проголосовать). Для моего использования я знаю, что у меня всегда будет объект Date, поэтому я просто добавил дату с помощью метода valid ().
Date.prototype.valid = function() {
return isFinite(this);
}
Теперь я могу просто написать это, и это гораздо более описательно, чем просто проверка isFinite в коде ...
d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
Ни один из этих ответов не работал для меня (проверен в Safari 6.0) при попытке подтвердить дату, такую как 2/31/2012, однако они отлично работают при попытке любой даты, превышающей 31.
Поэтому мне пришлось немного переборщить. Предполагая, что дата указана в формате mm/dd/yyyy
. Я использую @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
Ни одно из вышеперечисленных решений для меня не помогло,
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);
}
приведенный выше код будет видеть, когда JS делает 02/31/2012 по 03/02/2012, что его недействительно
Слишком много сложных ответов здесь уже, но достаточно простой строки (ES5):
Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;
или даже в ES6:
Date.prototype.isValid = d => !isNaN(Date.parse(d));
Хорошее решение! В моей библиотеке вспомогательных функций, теперь она выглядит так:
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());
}
Это просто сработало для меня
new Date('foo') == 'Invalid Date'; //is true
Однако это не сработало
new Date('foo') === 'Invalid Date'; //is false
Я думаю, что некоторые из них - долгий процесс. Мы можем сократить его, как показано ниже:
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;
}
Я написал эту функцию. Передайте ему строковый параметр, и он определит, является ли это допустимой датой или нет на основе этого формата «dd / MM / yyyy».
вот тест
input: "hahaha", output: false.
ввод: «29/2/2000», вывод: true.
ввод: «29/2/2001», вывод: 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;
}
}
Я объединил лучшие результаты производительности, которые я нашел вокруг этой проверки, если данный объект:
- это экземпляр даты ( эталон здесь )
- имеет действительную дату ( jsperf.com/detecting-an-invalid-date )
В результате получается следующее:
function isValidDate(input) {
if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
return false;
var time = input.getTime();
return time === time;
};
вы можете проверить действительный формат txDate.value с этой обрезкой. если он был в некорректном формате, то Date obejct не задан и возвращает значение null в dt.
var dt = new Date(txtDate.value)
if (isNaN(dt))
И как @ MiF предложил в короткие сроки
if(isNaN(new Date(...)))
кратчайший ответ, чтобы проверить действительную дату
if(!isNaN(date.getTime()))
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
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;
}