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


当前回答

这种类型的isValidDate使用一个处理闰年的正则表达式。它适用于常规日期,但不适用于iso日期:

函数isValidDate(值){return/((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/】)((1[8-9]\d{2})| 2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3})$)|(^(0?2)([/])(29)1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)| 13579][26])$)/测试(值)}功能测试(值){console.log(`${value}有效:${isValidDate(value)}`)}<buttonClick=“test('fo')”>foo</button><button on单击=“测试('2/20/2000')”>2/20/2000</button><button on单击=“测试('20/2/2000')”>20/2/2000</button><button单击=“测试('2022-02-02T18:51:53.517Z')”>2022-02-01T18:51:535.17Z</button>

其他回答

这种类型的isValidDate使用一个处理闰年的正则表达式。它适用于常规日期,但不适用于iso日期:

函数isValidDate(值){return/((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/】)((1[8-9]\d{2})| 2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3})$)|(^(0?2)([/])(29)1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)| 13579][26])$)/测试(值)}功能测试(值){console.log(`${value}有效:${isValidDate(value)}`)}<buttonClick=“test('fo')”>foo</button><button on单击=“测试('2/20/2000')”>2/20/2000</button><button on单击=“测试('20/2/2000')”>20/2/2000</button><button单击=“测试('2022-02-02T18:51:53.517Z')”>2022-02-01T18:51:535.17Z</button>

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

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

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

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

当我尝试验证日期(如2012年2月31日)时,这些答案都不适用(在Safari 6.0中测试),然而,当尝试任何大于31的日期时,它们都可以正常工作。

所以我不得不用蛮力。假设日期的格式为mm/dd/yyyy。我正在使用@broox答案:

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

对于日期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

var isDate_ = function(input) {
        var status = false;
        if (!input || input.length <= 0) {
          status = false;
        } else {
          var result = new Date(input);
          if (result == 'Invalid Date') {
            status = false;
          } else {
            status = true;
          }
        }
        return status;
      }