Проверьте, является ли строка значением даты - PullRequest
171 голосов
/ 16 сентября 2011

Какой простой способ проверить, является ли значение допустимой датой, допускается любой известный формат даты.

Например, у меня есть значения 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000, которые все должны распознаваться как значения даты, и значения 200, 10, 350, которые не должны распознаваться как значение даты. Какой самый простой способ проверить это, если это вообще возможно? Поскольку временные метки также будут разрешены.

Ответы [ 20 ]

207 голосов
/ 16 июня 2015

2015 Обновление

Это старый вопрос, но другие новые вопросы, такие как:

закройте как дубликаты этого, так что я думаю, что важно добавить некоторую свежую информацию здесь. Я пишу это, потому что мне стало страшно думать, что люди на самом деле копируют и вставляют часть кода, размещенного здесь, и используют его в работе.

Большинство ответов здесь либо используют некоторые сложные регулярные выражения, которые соответствуют только некоторым очень специфическим форматам и фактически делают это неправильно (например, соответствует 32 января, но не соответствует фактической дате ISO, как объявлено - см. demo ) или они пытаются передать что-либо конструктору Date и желают лучшего.

Использование момента

Как я объяснил в этом ответе в настоящее время есть библиотека для этого: Moment.js

Это библиотека для анализа, проверки, манипулирования и отображения дат в JavaScript, которая имеет гораздо более богатый API, чем стандартные функции обработки дат в JavaScript.

Это миниатюрный / gzipped 12kB и работает в Node.js и других местах:

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

Используя Момент, вы можете очень точно проверять действительные даты. Иногда очень важно добавить некоторые подсказки о формате, который вы ожидаете. Например, такая дата, как 22.06.2015, выглядит как действительная дата, если только вы не используете формат ДД / ММ / ГГГГ, и в этом случае эта дата должна быть отклонена как недействительная. Есть несколько способов, как вы можете сказать Моменту, какой формат вы ожидаете, например:

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

Аргумент true присутствует, поэтому Момент не будет пытаться проанализировать ввод, если он не точно не соответствует одному из предоставленных форматов (это должно быть поведение по умолчанию на мой взгляд).

Вы можете использовать внутренний формат:

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

И вы можете использовать несколько форматов в качестве массива:

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

См .: DEMO .

Другие библиотеки

Если вы не хотите использовать Moment.js, есть и другие библиотеки:

2016 Обновление

Я создал модуль immoment , похожий на (подмножество) Момент, но без неожиданностей, вызванных мутацией существующих объектов (см. документы для получения дополнительной информации).

2018 Обновление

Сегодня я рекомендую использовать Luxon для манипуляции с датой / временем вместо Moment, что (в отличие от Moment) делает все объекты неизменяемыми, поэтому нет никаких неприятных сюрпризов, связанных с неявной мутацией дат.

Подробнее

Смотри также:

Серия статей Роба Гравелла о библиотеках разбора дат в JavaScript:

Итог

Конечно, любой может попытаться заново изобрести колесо, написать регулярное выражение (но , пожалуйста, перед прочтением прочитайте ISO 8601 и RFC 3339) или вызвать встроенные конструкторы со случайными данными для разбора ошибки. сообщения типа 'Invalid Date' (Вы уверены, что это сообщение точно такое же на всех платформах? Во всех локалях? В будущем?) или вы можете использовать проверенное решение и использовать ваши время, чтобы улучшить его, а не изобретать его. Все перечисленные здесь библиотеки являются свободным программным обеспечением с открытым исходным кодом.

58 голосов
/ 31 июля 2014

Вот как я решил эту проблему в приложении, над которым я сейчас работаю:

обновлено на основе отзывов крилягара:

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

или ...

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

....

37 голосов
/ 16 сентября 2011

Достаточно ли Date.parse()?

См. Относительную Страница документации MDN .

20 голосов
/ 11 сентября 2014

new Date(date) === 'Invalid Date' работает только в Firefox и Chrome. IE8 (тот, который у меня есть на моей машине для тестирования) выдает NaN.

Как было указано в принятом ответе, Date.parse(date) также будет работать для чисел. Поэтому, чтобы обойти это, вы также можете проверить, что это не число (если вы хотите это подтвердить).

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 */
}
8 голосов
/ 10 марта 2014

Как насчет этого?Он проверит, является ли это объектом 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);
}

Я должен отметить, что это не проверяет строки, отформатированные в ISO, но с небольшой дополнительной работой с RegExp вы должны быть хороши.

7 голосов
/ 27 июля 2016

Ни один из ответов здесь не относится к проверке, является ли дата недействительной, например, 31 февраля. Эта функция обращается к ней, проверяя, равен ли возвращаемый месяц исходному месяцу, и проверяя, чтобы был представлен действительный год.*

4 голосов
/ 31 октября 2018

Используйте регулярное выражение для проверки.

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);
    }
3 голосов
/ 22 августа 2015

Я бы сделал это

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

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

Играть здесь

2 голосов
/ 16 января 2015

Вот минималистская версия.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
2 голосов
/ 02 августа 2018

Ссылаясь на все вышеупомянутые комментарии, я пришел к решению.

Это работает, если Дата прошла в формате ISO или вам нужно манипулировать для других форматов.

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");
}`

Вы можете играть здесь на JSFiddle

...