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


当前回答

您可以简单地使用moment.js

下面是一个示例:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

文档中的验证部分非常清楚。

此外,以下解析标志会导致无效日期:

溢出:日期字段的溢出,例如第13个月、一个月的第32天(或非闰年的2月29日)、一年的第367天等。溢出包含与#invalidAt匹配的无效单位的索引(见下文)-1表示无溢出。invalidMonth:无效的月份名称,例如moment('Marbruary','MMM');。包含无效的月份字符串本身,否则为空。空:不包含任何可解析内容的输入字符串,例如moment(“这是无意义的”);。布尔值。等


资料来源:http://momentjs.com/docs/

其他回答

我认为这是一个漫长的过程。我们可以简化如下:

 function isValidDate(dateString) {
        debugger;
        var dateStringSplit;
        var formatDate;

        if (dateString.length >= 8 && dateString.length<=10) {
            try {
                dateStringSplit = dateString.split('/');
                var date = new Date();
                date.setYear(parseInt(dateStringSplit[2]), 10);
                date.setMonth(parseInt(dateStringSplit[0], 10) - 1);
                date.setDate(parseInt(dateStringSplit[1], 10));

                if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {
                    return true;
                }
                else {
                    return false;
                }

            } catch (e) {
                return false;
            }
        }
        return false;
    }

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

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

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

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

您可以简单地使用moment.js

下面是一个示例:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

文档中的验证部分非常清楚。

此外,以下解析标志会导致无效日期:

溢出:日期字段的溢出,例如第13个月、一个月的第32天(或非闰年的2月29日)、一年的第367天等。溢出包含与#invalidAt匹配的无效单位的索引(见下文)-1表示无溢出。invalidMonth:无效的月份名称,例如moment('Marbruary','MMM');。包含无效的月份字符串本身,否则为空。空:不包含任何可解析内容的输入字符串,例如moment(“这是无意义的”);。布尔值。等


资料来源:http://momentjs.com/docs/

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

您可以通过以下方式检查Date对象d的有效性

d instanceof Date && isFinite(d)

为了避免跨帧问题,可以用

Object.prototype.toString.call(d) === '[object Date]'

在Borgar的回答中调用getTime()是不必要的,因为isNaN()和isFinite()都隐式转换为数字。