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


当前回答

您可以使用此scirpt检查txDate.value的有效格式。如果格式不正确,则Date obejct未实例化,并将null返回dt。

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

正如@MiF简短地建议的那样

 if(isNaN(new Date(...)))

其他回答

您应该使用:

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

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

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

此函数以字符分隔的数字格式验证字符串日期,例如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");
}

尝试以下操作:

if (!('null' === JSON.stringify(new Date('wrong date')))) console.log('correct');
else console.log('wrong');
Date.valid = function(str){
  var d = new Date(str);
  return (Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()));
}

https://gist.github.com/dustinpoissant/b83750d8671f10c414b346b16e290ecf

我会这样做:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d)) { // d.getTime() or d.valueOf() will also work
    // date object is not valid
  } else {
    // date object is valid
  }
} else {
  // not a date object
}

更新〔2018-05-31〕:如果您不关心来自其他JS上下文(外部窗口、框架或iframe)的Date对象,则可以使用更简单的形式:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}

更新[2021-02-01]:请注意,“无效日期”(2013-13-32)和“无效日期对象”(new date('fo'))之间存在根本区别。只有当date实例有效时,此答案才处理验证日期输入。