Обнаружение «недопустимой даты» экземпляра Date в JavaScript

Я хотел бы сказать разницу между действительными и недействительными объектами даты в 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функции?

  • Ash рекомендуется Date.parseдля анализа строк даты, что дает авторитетный способ проверить, является ли строка даты действительной.
  • Что бы я предпочел, если это возможно, это чтобы мой API принимал экземпляр Date и мог проверить / подтвердить, действителен ли он или нет. Решение Боргара делает это, но мне нужно протестировать его в разных браузерах. Мне также интересно, есть ли более элегантный способ.
  • Эш заставил меня задуматься о том, чтобы мой API вообще не принимал Dateэкземпляры, это будет проще всего проверить.
  • Боргар предложил проверить Dateэкземпляр, а затем проверить Dateзначение времени. Если дата недействительна, значение времени равно NaN. Я проверил с ECMA-262, и это поведение в стандарте, который именно то, что я ищу.
30.08.2009 11:34:40
Вы можете удалить оператор if, изменив тело функции на:return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
styfle 23.06.2011 23:35:12
@styfle - угадайте, что это предпочтение стиля: я считаю более понятным отделить проверку типа от логики равенства.
orip 27.06.2011 13:05:12
Дискурс @orip - это именно то, что крайне обескураживает в вопросах. Пожалуйста, обратитесь к соответствующим мета-темам, чтобы узнать причину этого. Размещение ответа на собственный вопрос в самом вопросе противоречит политике сайта. OTOH, благодарность за ответы и наличие «РЕДАКТИРОВАТЬ» в вашем ответе - типичный пух. Если вы хотите, чтобы ваш вопрос с самым высоким рейтингом идентифицировал вас как человека, который не знает, что такое SO и как его использовать, и не хочет изучать это, - будьте моим гостем.
user719662 5.07.2016 11:24:42
@orip: это не было "потеряно"; он все еще загромождает историю изменений вопроса, если вы хотите увидеть его снова. Но это не относится к вопросу. На 37k репутации вы должны знать это.
Lightness Races in Orbit 5.07.2016 15:34:40
Пожалуйста, прекратите редактировать войну. Правки по этому вопросу обсуждаются на мета . Пожалуйста, не редактируйте / откатывайте этот пост дальше. Если вы не согласны с предыдущими изменениями / откатами или у вас есть какие-либо комментарии относительно них, пожалуйста, пишите в этой мета-ветке, а не здесь.
Lundin 6.07.2016 06:10:54
30 ОТВЕТОВ
РЕШЕНИЕ

Вот как бы я это сделал:

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
}

Обновление [2018-05-31] : Если вас не интересуют объекты Date из других JS-контекстов (внешних окон, фреймов или фреймов), эта более простая форма может оказаться предпочтительной:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}
1274
31.05.2018 19:00:42
instanceof ломается через кадры. Утиная печать тоже может работать отлично: validDate == d && d.getTime &&! IsNaN (d.getTime ()); - Поскольку вопрос касается общей функции полезности, я предпочитаю быть более строгим.
Borgar 30.08.2009 12:14:13
@Borgar, только что нашел мой ответ: «Проблемы возникают, когда речь идет о сценариях в многокадровых средах DOM. В двух словах, объекты Array, созданные в одном iframe, не разделяют [[Prototype]] с массивами, созданными в другом iframe. Их конструкторы - это разные объекты, поэтому и проверка экземпляра, и проверка конструктора не удаются. "
Ash 31.08.2009 05:35:41
вам даже не нужно d.getTimeпростоisNan(d)
TecHunter 30.05.2013 08:26:50
Может быть упрощена , как это:d instanceof Date && !isNaN(d.getTime())
Zorgatone 7.04.2017 15:27:52
Спасибо за ответ, но я хотел бы подчеркнуть комментарии @Borgar и @blueprintChris: если я, например, проанализирую цифру, 1у меня все равно будет действительная дата, в результате Mon Jan 01 2001 00:00:00которой действительно будет дата, однако для целей моего приложения она совершенно бесполезна , Таким образом, по крайней мере, в моем случае требуется дополнительная проверка ввода. Этот ответ подтверждает dateObjectне Date!
dnhyde 22.09.2018 10:20:15

Вместо использования new Date()вы должны использовать:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse()возвращает отметку времени, целое число, представляющее количество миллисекунд с 01 января 1970 года. Он вернется, NaNесли не сможет проанализировать предоставленную строку даты.

254
10.04.2018 20:01:36
-1 Не знаю, почему это так много голосов, Date.parseзависит от реализации и определенно не заслуживает доверия для анализа общих строк даты. Не существует единого формата, который правильно анализируется в популярных браузерах, тем более всех используемых (хотя в конечном итоге формат ISO8601, указанный в ES5, должен быть в порядке).
RobG 25.05.2012 02:30:31
Если вы используете, new Date('foo')это в основном эквивалентно Date.parse('foo')методу. См .: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Так что, как сказал @RobG, это относится и к нему.
golddragon007 3.06.2019 07:52:30
Этот тест потерпит неудачу в Chrome. Например, Date.parse ('AAA-0001') в Chrome дает мне номер.
Nick 17.06.2019 04:28:47
не удалось ... определить все числовые значения
Hos Mercury 23.11.2019 22:42:13

Вы можете проверить действительность Dateобъекта dчерез

d instanceof Date && isFinite(d)

Чтобы избежать проблем с кадрами, можно заменить instanceofпроверку на

Object.prototype.toString.call(d) === '[object Date]'

Вызов , getTime()как в ответ Боргара нет необходимости , поскольку isNaN()и isFinite()как неявно преобразовать в число.

107
23.05.2017 12:02:46
Попробуйте это в chrome - Object.prototype.toString.call (новая дата («2013-07-09T19: 07: 9Z»)). Он вернет «[дата объекта]». Поэтому, по вашему мнению, «2013-07-09T19: 07: 9Z» должна быть действительной датой. Но это не так. Вы можете проверить это, снова в chrome, выполнив var dateStr = new Date ("2013-07-09T19: 07: 9Z"); dateStr Возвращает недопустимую дату.
Tintin 18.07.2013 00:06:43
@Tintin: это то, что isFinite()для - toString.call()только замена для instanceofчасти проверки
Christoph 18.07.2013 05:25:37
Будет ли сравнение с «[дата объекта]» работать с неанглийскими браузерами? Я сомневаюсь в этом.
kristianp 8.05.2015 01:04:35
@kristianp на самом деле это, вероятно, будет и, вероятно, даже является частью спецификации ECMAScript. Но, да, это выглядит некрасиво.
binki 11.12.2015 06:36:14
Для меня первый подход здесь - самый лучший вариант, хотя я не уверен, есть ли какое-то реальное преимущество использования isFiniteover isNaN(оба отлично работают Date(Infinity)). Кроме того, если вы хотите , состояние противоположное, это становится немного проще: if (!(date instanceof Date) || isNaN(date)).
Andrew 30.01.2018 01:33:30

Мне очень понравился подход Кристофа (но мне не хватило репутации, чтобы проголосовать за него). Для моего использования я знаю, что у меня всегда будет объект Date, поэтому я просто расширил дату с помощью метода valid ().

Date.prototype.valid = function() {
  return isFinite(this);
}

Теперь я могу просто написать это, и это гораздо более наглядно, чем просто проверка isFinite в коде ...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
26
23.11.2010 19:47:52
Продлеваете прототип? Это большой JavaScript-нет-нет!
Jasdeep Khalsa 8.06.2015 10:08:54
Upvoting из- isFiniteза меня работал отлично. Но да, бессмысленно расширять прототип. !isFiniteна Dateпоймать тот факт, что Dateесть Invalid Date. Также стоит отметить мой контекст внутри узла.
Staghouse 9.11.2019 05:38:55

Отличное решение! Включено в мою библиотеку вспомогательных функций, теперь это выглядит так:

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());
}
9
3.05.2011 16:44:25
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
23
6.07.2011 21:27:24
То же самое @Borgar написал 2 года назад ... Что нового ??
bluish 23.12.2011 13:34:17
Это две строки вместо уродливых вложенных операторов if.
Cypher 24.05.2013 18:53:14

Я думаю, что это длительный процесс. Мы можем сократить его, как показано ниже:

 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;
    }
1
11.08.2011 16:39:59
Был задан вопрос о том, как найти недопустимые экземпляры Date, а не строки, и, кроме того: кто сказал, что дата не может быть разделена чем-то другим, кроме косой черты?
Jon z 21.12.2012 22:22:40

Вдохновленный подходом Боргара, я удостоверился, что код не только проверяет дату, но и на самом деле удостоверяется, что дата является реальной датой, то есть такие даты, как 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!";
}
3
18.08.2011 15:52:40
Но ... методы выше (@ Borgar's и другие) уже проверяют этот тип достоверности ... Я не могу понять проблему.
bluish 23.12.2011 13:30:43
У Боргара нет - см. Его собственный комментарий к его ответу.
EML 29.12.2013 22:09:45
Это решение работает только тогда, когда ваша страна использует dd/MM/yyyyобозначения. Кроме того, он возвращается, trueкогда он действителен, а 'Invalid date!'если нет, лучше вернуть только 1 тип.
A1rPun 22.12.2015 10:00:54

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

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;
}

Для деталей, обратитесь к Проверке даты в JavaScript

16
3.02.2016 08:28:28
strне используется
samis 2.02.2016 18:21:58

Вы можете проверить действительный формат txDate.value с этим scirpt. если он был в неправильном формате, объект Date не был создан и возвращал ноль в dt.

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

И как @ MiF's предложил вкратце

 if(isNaN(new Date(...)))
17
7.10.2017 06:50:50
isNaN (новая дата (...)) - простой и короткий метод
MiF 6.10.2017 10:27:58
@MiF да, я обновляю свой ответ твоим предложением;) спасибо
Yusef 7.10.2017 06:51:40

Ни одно из вышеперечисленных решений не помогло мне.

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 делает 31.02.2012 в 03.02.2012, что он не действителен

5
31.08.2012 07:12:22
Хорошо, но это проверяет, является ли строка датой в формате M / D / Y, а не «разницей между действительными и недействительными объектами даты». Это не совсем то, о чем идет речь.
Borgar 1.09.2012 12:00:04
причина, по которой он проверяется на соответствие формату, состоит в том, чтобы проверить, изменилась ли дата после анализа
John 10.09.2012 11:29:27
Разве ОП не запрашивает метод для возврата логического значения, а не отформатированной строки?
barrypicker 21.11.2014 20:39:42
Пример кода возвращает логическое значение, форматирование играет роль в тестировании некоторых недопустимых случаев.
John 25.11.2014 11:52:53

Ни один из этих ответов не сработал для меня (проверено в Safari 6.0) при попытке проверить дату, такую ​​как 31.02.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
6
1.02.2014 16:49:38
(новая дата ('30.02.2014')). valid () возвращает true
Andre Figueiredo 31.01.2014 11:39:00
Прошло некоторое время с тех пор, как я ответил на это, но вам могут понадобиться оба условия возврата, в том числе&& value.split('/')[0] == (d.getMonth()+1);
Dex 31.01.2014 22:22:25
Использование new Date('string date')эквивалентно Date.parse('string date'), см .: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…, так что вы можете получить ложные значения true или false.
golddragon007 3.06.2019 07:50:10

Мое решение - просто проверить, есть ли у вас действительный объект даты:

Реализация

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();
};  

Применение

var d = new Date("lol");

console.log(d.isValid()); // false

d = new Date("2012/09/11");

console.log(d.isValid()); // true
85
11.09.2012 15:03:31
isNaNболее явный способ проверки на NaN
orip 11.09.2012 17:16:17
И все же, вы всегда найдете людей, пишущих свои собственные версии :) documentcloud.github.com/underscore/docs/…
Ash Clarke 12.09.2012 09:00:45
так как я уважаю underscore.js, это вызвало некоторые исследования. isNaN("a") === true, пока ("a" !== "a") === false. Об этом стоит подумать. +1
orip 12.09.2012 09:14:19
Я проверил производительность для 3 основных решений, которые я нашел здесь. Поздравляю, вы победитель! jsperf.com/detecting-an-invalid-date
zVictor 25.07.2014 09:40:09
@ Али Это допустимый объект даты. new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time), Если вы передаете строку в конструктор даты, вы должны передать стандартизированную строку, чтобы получить надежный результат. В частности, «Строка должна быть в формате, распознаваемом методом Date.parse ()». developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ash Clarke 3.06.2016 09:33:53
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;
}
5
14.09.2012 18:52:43

Хотелось бы отметить, что в виджете DatePicker пользовательского интерфейса jQuery есть очень хороший метод утилиты проверки даты, который проверяет формат и действительность (например, даты 01/33/2013 не допускаются).

Даже если вы не хотите использовать виджет datepicker на своей странице в качестве элемента пользовательского интерфейса, вы всегда можете добавить его библиотеку .js на свою страницу и затем вызвать метод validator, передав в него значение, которое вы хотите проверить. Чтобы сделать жизнь еще проще, в качестве входных данных используется строка, а не объект JavaScript Date.

Смотрите: http://api.jqueryui.com/datepicker/

Он не указан как метод, но он есть как служебная функция. Поиск на странице "parsedate", и вы найдете:

$ .datepicker.parseDate (формат, значение, настройки) - извлечение даты из строкового значения в указанном формате.

Пример использования:

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.';
}

(Подробнее о форматах дат можно узнать по адресу http://api.jqueryui.com/datepicker/#utility-parseDate ).

В приведенном выше примере вы не увидите предупреждающее сообщение, поскольку '01 / 03/2012 'является датой, действующей в календаре, в указанном формате. Однако, например, если вы сделали 'stringval' равным '13/04/2013', вы получите сообщение с предупреждением, поскольку значение '13/04/2013' недействительно для календаря.

Если переданное строковое значение успешно проанализировано, значением 'testdate' будет объект Javascript Date, представляющий переданное строковое значение. Если нет, это было бы неопределенным.

38
7.07.2016 08:35:51
Upvote для того, чтобы быть первым ответом, работающим с не английскими / местными форматами даты.
ax. 17.07.2015 16:06:52

Объект Date to string - более простой и надежный способ определить, являются ли оба поля действительными. Например, если вы введете это «-------» в поле ввода даты. Некоторые из приведенных выше ответов не сработают.

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}.');
2
12.08.2013 20:41:35

Вы можете просто использовать moment.js

Вот пример:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

Раздел валидации в документации вполне понятен.

А также, следующие флаги синтаксического анализа приводят к неверной дате:

  • overflow: Переполнение поля даты, например, 13-го месяца, 32-го дня месяца (или 29 февраля для не високосных годов), 367-го дня года и т. Д. Переполнение содержит индекс недопустимой единицы соответствовать #invalidAt (см. ниже); -1 означает отсутствие переполнения.
  • invalidMonth: Неверное название месяца, например, момент («Март», «ММММ»); Содержит недопустимую строку месяца, либо нуль.
  • empty: Входная строка, которая не содержит ничего доступного для анализа, например момент («это чепуха»); Boolean.
  • И т.п.

Источник: http://momentjs.com/docs/

43
11.12.2015 07:27:00
Лучшее решение, чрезвычайно простое в реализации, работает с любым форматированием (в моем случае это дд / мм / гггг), также знает високосные годы и не конвертирует недопустимые даты (т.е. 29/02/2015) в действительные (т.е. 30/03/2015). Чтобы проверить дату в формате dd / MM / yyyy, я просто должен был использоватьmoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin 14.07.2015 14:26:09
Это использование момента было объявлено устаревшим :(
James Sumners 25.09.2015 13:00:53
Это использование не было амортизировано. Момент вызова (ввод) без форматной строки амортизируется (если вход не отформатирован в формате ISO).
Chet 16.02.2016 21:35:16
Этот метод может быть очень медленным при обработке многих дат. Лучше использовать регулярные выражения в этих случаях.
Grid Trekkor 18.07.2016 19:03:42
Использование moment.js может быть простым, но это огромные накладные расходы. Эта библиотека огромна. Я понизил твой ответ.
Mick 21.02.2019 12:17:22

Для компонентов даты на основе int 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)
1
8.11.2013 12:49:33

Вы можете преобразовать дату и время в миллисекунды getTime ()

этот getTime()метод возвращает не число, NaNесли оно недействительно

if(!isNaN(new Date("2012/25/255").getTime()))
  return 'valid date time';
  return 'Not a valid date time';
1
31.01.2014 21:39:49
Это не работает, !isNaN(new Date("2/30/2012").getTime())возвращает истину
Dex 1.02.2014 23:17:45

Это только сработало для меня

new Date('foo') == 'Invalid Date'; //is true

Однако это не сработало

new Date('foo') === 'Invalid Date'; //is false
9
6.01.2014 02:36:02
Я считаю, что это зависит от браузера.
barrypicker 21.11.2014 20:40:56
@barrypicker Что вы имеете в виду, это зависит от браузера?
Ajil O. 26.07.2017 11:31:36
Вы можете сделать: `${new Date('foo')}` === 'Invalid Date'
Daniele Vrut 23.01.2020 12:43:33
var isDate_ = function(input) {
        var status = false;
        if (!input || input.length <= 0) {
          status = false;
        } else {
          var result = new Date(input);
          if (result == 'Invalid Date') {
            status = false;
          } else {
            status = true;
          }
        }
        return status;
      }
0
16.01.2014 06:47:21

Я написал эту функцию. Передайте ему строковый параметр, и он будет определять, является ли это действительной датой или нет, основываясь на этом формате «дд / мм / гггг».

вот тест

ввод: "хахаха", вывод: ложь.

вход: "29/2/2000", выход: true.

вход: "29/2/2001", выход: ложь.

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;
    }
}
4
25.02.2014 11:22:44

Выбранный ответ отличный, и я тоже им пользуюсь. Однако, если вы ищете способ проверки ввода даты пользователем, вы должны знать, что объект Date очень настойчив в превращении недопустимых аргументов конструкции в допустимые. Следующий код модульного теста иллюстрирует эту точку:

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());
});
2
18.06.2014 18:14:23

Я объединил лучшие результаты производительности, которые я нашел вокруг этой проверки, если данный объект:

Результат следующий:

function isValidDate(input) {
  if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
    return false;

  var time = input.getTime();
  return time === time;
};
3
30.04.2015 09:00:39

Эта функция проверяет строковую дату в цифровых форматах, разделенных символом, например, дд / мм / гггг, мм / дд / гггг

/*
Param  : 
1)the date in string data type 
2)[optional - string - default is "/"] the date delimiter, most likely "/" or "-"
3)[optional - int - default is 0] the position of the day component when the date string is broken up via the String.split function (into arrays)
4)[optional - int - default is 1] the position of the month component when the date string is broken up via the String.split function (into arrays)
5)[optional - int - default is 2] the position of the year component when the date string is broken up via the String.split function (into arrays)

Return : a javascript date is returned if the params are OK else null
*/
function IsValidDate(strDate, strDelimiter, iDayPosInArray, iMonthPosInArray, iYearPosInArray) {
    var strDateArr; //a string array to hold constituents day, month, and year components
    var dtDate; //our internal converted date
    var iDay, iMonth, iYear;


    //sanity check 
    //no integer checks are performed on day, month, and year tokens as parsing them below will result in NaN if they're invalid
    if (null == strDate || typeof strDate != "string")
        return null;

    //defaults
    strDelimiter = strDelimiter || "/";
    iDayPosInArray = undefined == iDayPosInArray ? 0 : iDayPosInArray;
    iMonthPosInArray = undefined == iMonthPosInArray ? 1 : iMonthPosInArray;
    iYearPosInArray = undefined == iYearPosInArray ? 2 : iYearPosInArray;

    strDateArr = strDate.split(strDelimiter);

    iDay = parseInt(strDateArr[iDayPosInArray],10);
    iMonth = parseInt(strDateArr[iMonthPosInArray],10) - 1; // Note: months are 0-based
    iYear = parseInt(strDateArr[iYearPosInArray],10);

    dtDate = new Date(
        iYear,
        iMonth, // Note: months are 0-based
        iDay);

    return (!isNaN(dtDate) && dtDate.getFullYear() == iYear && dtDate.getMonth() == iMonth && dtDate.getDate() == iDay) ? dtDate : null; // Note: months are 0-based
}

Пример вызова:

var strDate="18-01-1971";

if (null == IsValidDate(strDate)) {

  alert("invalid date");
}
0
4.09.2018 06:18:48

Обычно я придерживаюсь любой имплантации даты в стеке браузера. Это означает, что вы всегда получите «Недопустимую дату» при вызове toDateString () в Chrome, Firefox и Safari с даты этого ответа.

if(!Date.prototype.isValidDate){
  Date.prototype.isValidDate = function(){
    return this.toDateString().toLowerCase().lastIndexOf('invalid') == -1;
  };
}

Я не проверял это в IE, хотя.

1
26.08.2014 18:51:45
function isValidDate(date) {
  return !! (Object.prototype.toString.call(date) === "[object Date]" && +date);
}
1
23.04.2015 17:45:06
Пожалуйста, отредактируйте это, чтобы предоставить дополнительную информацию / объяснение различных частей "магии", которую вы выполняете.
Ryan Ransford 23.04.2015 17:46:20
рассмотрим + date как date.toNumber (на самом деле нет метода .toNumber) и parseInt (date)! == + date, parseInt (date) === NaN. Оператор "+" - это магия в js. а не кросс-браузер: попробуйте это: [новая дата (Date.now ()) + 1, + новая дата (Date.now ()) + 1]
Abdullah Aydın 11.01.2016 16:13:43
function isValidDate(strDate) {
    var myDateStr= new Date(strDate);
    if( ! isNaN ( myDateStr.getMonth() ) ) {
       return true;
    }
    return false;
}

Назови это так

isValidDate(""2015/5/2""); // => true
isValidDate(""2015/5/2a""); // => false
2
23.08.2015 03:50:30

Для проектов Angular.js вы можете использовать:

angular.isDate(myDate);
9
18.09.2015 00:27:40
Это возвращает истину при тестировании объекта даты, который был инициализирован с недопустимой датой.
dchhetri 3.08.2016 19:08:37

Этот вариант isValidDate использует регулярное выражение, которое обрабатывает високосные годы:

function isValidDate(value)
{
    return /((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(29)([/])([2468][048]00)$)|(^(0?2)([/])(29)([/])([3579][26]00)$)|(^(0?2)([/])(29)([/])([1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)|(^(0?2)([/])(29)([/])([2-9][0-9][2468][048])$)|(^(0?2)([/])(29)([/])([1][89][13579][26])$)|(^(0?2)([/])(29)([/])([2-9][0-9][13579][26])$))/.test(value)
}
0
17.11.2015 15:49:19