我想知道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对象d的有效性

d instanceof Date && isFinite(d)

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

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

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

其他回答

我真的很喜欢克里斯托夫的方法(但没有足够的声誉来投票支持)。对于我的用途,我知道我将始终有一个Date对象,所以我只是用valid()方法扩展了日期。

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

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

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }

我看到了一些与这个小片段非常接近的答案。

JavaScript方式:

函数isValidDate(dateObject){return new Date(dateObject).toString()!=='无效日期';}console.log(isValidDate('WTH'));//->假的console.log(isValidDate(新日期('WTH')));//->假的console.log(isValidDate(new Date()));//->真的

ES2015方式:

const isValidDate=dateObject=>新日期(dateObject).toString()!=='无效日期';console.log(isValidDate('WTH'));//->假的console.log(isValidDate(新日期('WTH')));//->假的console.log(isValidDate(new Date()));//->真的

您可以简单地使用moment.js

下面是一个示例:

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

文档中的验证部分非常清楚。

此外,以下解析标志会导致无效日期:

溢出:日期字段的溢出,例如第13个月、一个月的第32天(或非闰年的2月29日)、一年的第367天等。溢出包含与#invalidAt匹配的无效单位的索引(见下文)-1表示无溢出。invalidMonth:无效的月份名称,例如moment('Marbruary','MMM');。包含无效的月份字符串本身,否则为空。空:不包含任何可解析内容的输入字符串,例如moment(“这是无意义的”);。布尔值。等


资料来源:http://momentjs.com/docs/

还没有人提到它,所以符号也是一种方法:

Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date") // true

Symbol.for(new Date()) === Symbol.for("Invalid Date") // false

console.log('Symbol.for(新日期(“Peter”))===Symbol.ffor(“无效日期”)',Symbol.fo(新日期)===符号.for(“无效时间”))//trueconsole.log('Symbol.for(new Date())==Symbol.ffor(“无效日期”)',Symbol.fo(newDate()==符号.for(“无效时间”))//false

注意:https://caniuse.com/#search=Symbol

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

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

结果如下:

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

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