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


当前回答

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

其他回答

这种类型的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>

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

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()));//->真的

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

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

您应该使用:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse()返回一个时间戳,一个整数表示自1970年1月1日以来的毫秒数。如果无法解析提供的日期字符串,它将返回NaN。

我想提到的是,jQueryUIDatePicker小部件有一个非常好的日期验证器实用程序方法,可以检查格式和有效性(例如,不允许2013年1月33日的日期)。

即使您不想将页面上的datepicker小部件用作UI元素,也可以始终将其.js库添加到页面中,然后调用验证器方法,将要验证的值传递给它。

参见:http://api.jqueryui.com/datepicker/

它没有被列为一种方法,但它是作为一种实用函数存在的。在页面中搜索“parsedate”,您会发现:

$.datepicker.parseDate(格式、值、设置)-从具有指定格式的字符串值中提取日期。

示例用法:

var stringval = '01/03/2012';
var testdate;

try {
  testdate = $.datepicker.parseDate('mm/dd/yy', stringval);
             // Notice 'yy' indicates a 4-digit year value
} catch (e)
{
 alert(stringval + ' is not valid.  Format must be MM/DD/YYYY ' +
       'and the date value must be valid for the calendar.';
}

(有关指定日期格式的详细信息,请参阅http://api.jqueryui.com/datepicker/#utility-parseDate)

在上面的示例中,您不会看到警报消息,因为“01/03/2012”是指定格式的日历有效日期。但是,例如,如果将“stringval”设置为“13/04/2013”,则会收到警告消息,因为值“13/04/13”不是日历有效值。

如果成功解析了传入的字符串值,“testdate”的值将是表示传入字符串值的Javascript Date对象。如果没有,它将是未定义的。