我想知道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 fns”有一个函数isValid。以下文件摘自其网站:

isValid argument Before v2.0.0 v2.0.0 onward
new Date() true true
new Date('2016-01-01') true true
new Date('') false false
new Date(1488370835081) true true
new Date(NaN) false false
'2016-01-01' TypeError false
'' TypeError false
1488370835081 TypeError true
NaN TypeError false

其他回答

function isValidDate(date) {
  return !! (Object.prototype.toString.call(date) === "[object Date]" && +date);
}

我认为这是一个漫长的过程。我们可以简化如下:

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

对于日期FNS,有一个名为isExists的函数。它检查日期是否存在(2月31日不应存在)。

示例:

// For the valid date:
const result = isExists(2018, 0, 31)
//=> true
// For the invalid date:
const result = isExists(2018, 1, 31) 
//=> false

文档:https://date-fns.org/v2.28.0/docs/isExists

您可以通过以下方式检查Date对象d的有效性

d instanceof Date && isFinite(d)

为了避免跨帧问题,可以用

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

在Borgar的回答中调用getTime()是不必要的,因为isNaN()和isFinite()都隐式转换为数字。

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

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

结果如下:

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

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