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


当前回答

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

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

其他回答

我想提到的是,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对象。如果没有,它将是未定义的。

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

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

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

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

日期对象到字符串是检测两个字段是否为有效日期的更简单可靠的方法。例如,如果在日期输入字段中输入此“-------”。上面的一些答案行不通。

jQuery.validator.addMethod("greaterThan", 

    function(value, element, params) {
        var startDate = new Date($(params).val());
        var endDate = new Date(value);

        if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {
            return false;
        } else {
            return endDate > startDate;
        }
    },'Must be greater than {0}.');