我想知道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检查了一下,这种行为符合标准,这正是我所要的。


当前回答

受到Borgar方法的启发,我确保代码不仅验证了日期,而且实际上确保了日期是真实的日期,这意味着2011年9月31日和2011年2月29日这样的日期是不允许的。

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

其他回答

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

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

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

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

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

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

这里已经有太多复杂的答案,但简单的一行就足够了(ES5):

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

或甚至在ES6中:

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

所以我喜欢@Ask Clarke的回答,通过为无法通过var d=new Date(d)的日期添加try-catch块,几乎没有什么改进-

function checkIfDateNotValid(d) {
        try{
            var d = new Date(d);
            return !(d.getTime() === d.getTime()); //NAN is the only type which is not equal to itself.
        }catch (e){
            return true;
        }

    }