сравнение - Обнаружение экземпляра даты «недействительной даты» в 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;
    }
}

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

В результате получается следующее:

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






date