Обнаружение «недопустимой даты» экземпляра Date в JavaScript - PullRequest
1284 голосов
/ 30 августа 2009

Я бы хотел сказать разницу между действительными и недействительными объектами даты в 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 , и это поведение в стандарте, что именно то, что я ищу.

Ответы [ 40 ]

1079 голосов
/ 30 августа 2009

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

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);
}
236 голосов
/ 30 августа 2009

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

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

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

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

99 голосов
/ 30 августа 2009

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

d instanceof Date && isFinite(d)

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

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

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

76 голосов
/ 11 сентября 2012

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

Осуществление

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
62 голосов
/ 04 июля 2016

кратчайший ответ для проверки действительной даты

if(!isNaN(date.getTime()))
42 голосов
/ 15 октября 2013

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

Вот пример:

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

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

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

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

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

37 голосов
/ 15 февраля 2013

Хотелось бы отметить, что у виджета DatePicker пользовательского интерфейса jQuery есть очень хороший метод утилиты проверки даты, который проверяет формат и действительность (например, даты не доступны с 01.01.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, представляющий переданное строковое значение. Если нет, это было бы неопределенным.

22 голосов
/ 23 ноября 2010

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

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

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

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
20 голосов
/ 07 июля 2011
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
15 голосов
/ 27 октября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...