我想知道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实例,并能够检查/断言它是否有效。Borgar的解决方案做到了这一点,但我需要在浏览器上进行测试。我还想知道是否有更优雅的方式。Ash让我考虑不让我的API接受Date实例,这是最容易验证的。Borgar建议测试Date实例,然后测试Date的时间值。如果日期无效,则时间值为NaN。我用ECMA-262检查了一下,这种行为符合标准,这正是我所要的。


当前回答

Date.valid = function(str){
  var d = new Date(str);
  return (Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()));
}

https://gist.github.com/dustinpoissant/b83750d8671f10c414b346b16e290ecf

其他回答

这对我很有效

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

然而,这并不奏效

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

NaN是假的。invalidDateObject.valueOf()为NaN。

const d = new Date('foo');
if (!d.valueOf()) {
  console.error('Not a valid date object');
}
else {
  // act on your validated date object
}

尽管valueOf()在功能上等同于getTime(),但我觉得在这种情况下更合适。

我已经编写了这个函数。给它传递一个字符串参数,它将根据格式“dd/MM/yyyy”确定它是否为有效日期。

这是一个测试

输入:“哈哈哈”,输出: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;
    }
}

我结合了我在检查中发现的最佳性能结果,如果给定对象:

是Date实例(此处为基准)具有有效日期(此处为基准)

结果如下:

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

  var time = input.getTime();
  return time === time;
};

这里只有少数人(@Zen、@Dex、@wanglab……)对javascript容忍在2月、4月、6月等月份溢出日数。。。

如果指定要处理的格式(即yyyy-MM-dd),则在解决方案中根本不必使用javascript对象Date。

函数leapYear(年){return((年%4==0)&&(年%100!=0))||(年%400==0);}函数validateStr(dateStr){if(/^[0-9][0-9][0-9][0-9][0-9]-[0-9][9-9]-[0-9][0-9][0-9]$/.test(dateStr)==false){return false;}var m=parseInt(dateStr.substr(5,2));var d=parseInt(dateStr.substr(8,2));var y=parseInt(dateStr.substr(0,4));//您可以为大于5000:-D的值添加年度检查如果(m>12||d>31){return false;}否则,如果(m==2&&d>28){如果(d==29){if(!leapYear(y)){return false;}}其他{return false;}}否则如果(d>30&&(m==4||m==6||m==9||m===11)){return false;}返回true;}console.log(“2020-02-29:”+validateDateStr(“2020:02-29”));//真的console.log(“2020-02-30:”+validateDateStr(“2020:02-30”));//假的console.log(“2022-02-29:”+validateDateStr(“20202-02-29”));//假的console.log(“2021-02-28:”+validateDateStr(“2011-02-28”));//真的console.log(“2020-03-31:”+validateDateStr(“2020:03-31”));//真的console.log(“2020-04-30:”+validateDateStr(“2020:04-30”));//真的console.log(“2020-04-31:”+validateDateStr(“2020:04-31”));//假的console.log(“2020-07-31:”+validateDateStr(“2020:07-31”));//真的console.log(“2020-07-32:”+validateDateStr(“2020:07-32”));//假的控制台日志(“2020-08-31:”+validateDateStr(“2020:08-31”));//真的console.log(“2020-12-03:”+validateDateStr(“2020-102-03”));//真的console.log(“2020-13-03:”+validateDateStr(“2020-103-03”));//假的console.log(“0020-12-03:”+validateDateStr(“0020-102-03”));//真的//无效正则表达式console.log(“20-12-03:”+validateDateStr(“20-12-103”));//假的console.log(“2020-012-03:”+validateDateStr(“2020:012-03”));//假的console.log(“2020-12-003:”+validateDateStr(“2020-102-003”));//假的