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


当前回答

NaN是假的。invalidDateObject.valueOf()为NaN。

const d = new Date('foo');
if (!d.valueOf()) {
  console.error('Not a valid date object');
}
else {
  // act on your validated date object
}

尽管valueOf()在功能上等同于getTime(),但我觉得在这种情况下更合适。

其他回答

检查日期是否为有效日期对象的另一种方法:

const isValidDate = (date) => 
  typeof date === 'object' && 
  typeof date.getTime === 'function' && 
  !isNaN(date.getTime())

在这么多人在我面前尝试之后,我为什么要写第48个答案?大多数答案部分正确,不会在任何情况下都有效,而其他答案则是不必要的冗长和复杂。下面是一个非常简洁的解决方案。这将检查它是否为日期类型,然后检查有效的日期对象:

return x instanceof Date && !!x.getDate();

现在来解析日期文本:大多数解决方案都使用date.parse()或“new date()”——这两种方法都会在某些情况下失败,而且可能很危险。JavaScript解析多种格式,并且依赖于本地化。例如,像“1”和“blah-123”这样的字符串将解析为有效日期。

还有一些帖子要么使用大量代码,要么使用一英里长的RegEx,要么使用第三方框架。

这是验证日期字符串的非常简单的方法。

函数isDate(txt){var matches=txt.match(/^\d?\d\/(\d?\d)\/\d{4}$/)//注:RegEx中的“日”用括号括起来回来匹配&&!!Date.parse(txt)&&newDate(txt).getDate()==匹配[1];}测试功能<br/><br/><input id=“dt”value=“12/21/2020”><input type=“button”value=“validate”id=“btnAction”onclick=“document.getElementById('slt').innerText=isDate(document.getElement ById('dt').value)”><br/><br/>结果:<span id=“rslt”></span>

isDate的第一行使用简单的RegEx解析输入文本,以验证日期格式mm/dd/yyyy或m/d/yyyy。对于其他格式,您需要相应地更改RegEx,例如,对于dd-mm-yyyy,RegEx变为/^(\d?\d)-\d?\d-\d{4}$/

如果解析失败,“matches”为空,否则将存储月份的日期。第二行进行了更多测试,以确保它是有效日期,并消除了类似2021 9月31日(JavaScript允许)的情况。最后请注意,double-back(!!)将“falsy”转换为布尔值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

此函数以字符分隔的数字格式验证字符串日期,例如dd/mm/yyyy、mm/dd/yyyy

/*
Param  : 
1)the date in string data type 
2)[optional - string - default is "/"] the date delimiter, most likely "/" or "-"
3)[optional - int - default is 0] the position of the day component when the date string is broken up via the String.split function (into arrays)
4)[optional - int - default is 1] the position of the month component when the date string is broken up via the String.split function (into arrays)
5)[optional - int - default is 2] the position of the year component when the date string is broken up via the String.split function (into arrays)

Return : a javascript date is returned if the params are OK else null
*/
function IsValidDate(strDate, strDelimiter, iDayPosInArray, iMonthPosInArray, iYearPosInArray) {
    var strDateArr; //a string array to hold constituents day, month, and year components
    var dtDate; //our internal converted date
    var iDay, iMonth, iYear;


    //sanity check 
    //no integer checks are performed on day, month, and year tokens as parsing them below will result in NaN if they're invalid
    if (null == strDate || typeof strDate != "string")
        return null;

    //defaults
    strDelimiter = strDelimiter || "/";
    iDayPosInArray = undefined == iDayPosInArray ? 0 : iDayPosInArray;
    iMonthPosInArray = undefined == iMonthPosInArray ? 1 : iMonthPosInArray;
    iYearPosInArray = undefined == iYearPosInArray ? 2 : iYearPosInArray;

    strDateArr = strDate.split(strDelimiter);

    iDay = parseInt(strDateArr[iDayPosInArray],10);
    iMonth = parseInt(strDateArr[iMonthPosInArray],10) - 1; // Note: months are 0-based
    iYear = parseInt(strDateArr[iYearPosInArray],10);

    dtDate = new Date(
        iYear,
        iMonth, // Note: months are 0-based
        iDay);

    return (!isNaN(dtDate) && dtDate.getFullYear() == iYear && dtDate.getMonth() == iMonth && dtDate.getDate() == iDay) ? dtDate : null; // Note: months are 0-based
}

示例调用:

var strDate="18-01-1971";

if (null == IsValidDate(strDate)) {

  alert("invalid date");
}

对于Angular.js项目,您可以使用:

angular.isDate(myDate);