在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函数的想法吗?

  • 建议Date.parse使用Ash 来分析日期字符串,这为检查日期字符串是否有效提供了一种权威方法。
  • 如果可能的话,我希望我的API接受Date实例,并能够检查/确认它是否有效。Borgar的解决方案可以做到这一点,但是我需要在浏览器中对其进行测试。我也想知道是否有更优雅的方法。
  • Ash使我考虑完全不让我的API接受Date实例,这将最容易验证。
  • Borgar建议先测试一个Date实例,然后再测试Date的时间值。如果日期无效,则时间值为NaN我使用ECMA-262进行了检查,这种行为符合标准,这正是我要寻找的。
蛋蛋前端神无2020/03/09 20:55:20

For int 1-based components of a date:

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

Tests:

    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)
卡卡西逆天2020/03/09 20:55:20

I think some of this is a long process. We can cut it short as shown below:

 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;
    }
逆天樱2020/03/09 20:55:20

Simple and elegant solution:

const date = new Date(`${year}-${month}-${day} 00:00`)
const isValidDate = (Boolean(+date) && date.getDate() == day)

sources:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] Incorrect date shown in new Date() in JavaScript

樱GO2020/03/09 20:55:20
function isValidDate(strDate) {
    var myDateStr= new Date(strDate);
    if( ! isNaN ( myDateStr.getMonth() ) ) {
       return true;
    }
    return false;
}

Call it like this

isValidDate(""2015/5/2""); // => true
isValidDate(""2015/5/2a""); // => false
L西门2020/03/09 20:55:20

I combined the best performance results I found around that check if a given object:

The result is the following:

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

  var time = input.getTime();
  return time === time;
};
卡卡西Tom2020/03/09 20:55:20

None of the above solutions worked for me what did work however is

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

the code above will see when JS makes 02/31/2012 into 03/02/2012 that its not valid

老丝达蒙2020/03/09 20:55:20
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;
}
Stafan小宇宙2020/03/09 20:55:20

None of these answers worked for me (tested in Safari 6.0) when trying to validate a date such as 2/31/2012, however, they work fine when trying any date greater than 31.

So I had to brute force a little. Assuming the date is in the format mm/dd/yyyy. I am using @broox answer:

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
樱樱2020/03/09 20:55:20

For Angular.js projects you can use:

angular.isDate(myDate);
蛋蛋神乐2020/03/09 20:55:20

我使用以下代码验证年份,月份和日期的值。

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中的检查日期。

Stafan古一2020/03/09 20:55:20

Too many complicated answers here already, but a simple line is sufficient (ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

or even in ES6 :

Date.prototype.isValid = d => !isNaN(Date.parse(d));
DavaidHarry2020/03/09 20:55:20

我真的很喜欢Christoph的方法(但没有足够的声誉来投票赞成)。对于我的使用,我知道我将始终有一个Date对象,因此我只是使用有效的()方法扩展了日期。

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

现在我可以编写它了,它比在代码中检查isFinite更具描述性...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
阿飞神乐2020/03/09 20:55:20

检查有效日期的最短答案

if(!isNaN(date.getTime()))
GreenNear2020/03/09 20:55:20

我的解决方案是仅检查您是否获得了有效的日期对象:

实作

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
古一斯丁猴子2020/03/09 20:55:20

这是我的处理方式:

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]:如果您不关心其他JS上下文(外部窗口,框架或iframe)中的Date对象,则首选以下简单形式:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}