我想告诉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实例并且能够检查/断言它是否's valid or not. Borgar'解决方案是这样做的,但我需要跨浏览器测试它 . 我也想知道是否有更优雅的方式 .
-
Ash让我觉得我的API根本没有接受
Date
实例,这最容易验证 . -
Borgar建议测试
Date
实例,然后测试Date
的时间值 . 如果日期无效,则时间值为NaN
. 我用ECMA-262检查了这个行为是在标准中,这正是我正在寻找的 .
30 回答
这里有太多复杂的答案,但一条简单的线就足够了(ES5):
甚至在ES6中:
选择的答案非常好,我也在使用它 . 但是,如果您正在寻找一种验证用户日期输入的方法,您应该知道Date对象非常持久地将看似无效的构造参数变为有效的构造参数 . 以下单元测试代码说明了这一点:
而不是使用
new Date()
,你应该使用:Date.parse()
返回一个时间戳,一个整数,表示自01 / Jan / 1970以来的毫秒数 . 如果它无法解析提供的日期字符串,它将返回NaN
.上述解决方案都没有为我工作,但是工作是什么
上面的代码将看到JS何时将02/31/2012变为03/02/2012,它无效
对于日期的基于int 1的组件:
测试:
我认为其中一些是漫长的过程 . 我们可以缩短它,如下所示:
Date对象到字符串是更简单可靠的方法来检测两个字段是否都是有效日期 . 例如如果在日期输入字段中输入“-------” . 上面的一些答案是行不通的 .
检查有效日期的最短答案
像这样称呼它
我真的很喜欢克里斯托夫的方法(但没有足够的声誉来投票) . 对于我的使用,我知道我将始终有一个Date对象,所以我只使用valid()方法扩展日期 .
现在我可以写这个,它比仅仅在代码中检查isFinite更具描述性......
你可以用这个scirpt检查txDate.value的有效格式 . 如果格式不正确,则Date obejct未实例化并返回null为dt .
正如@ MiF的建议那么简短
我写过这个函数 . 传递一个字符串参数,它将根据这种格式“dd / MM / yyyy”确定它是否是有效日期 .
这是一个测试
输入:“hahaha”,输出:false .
输入:“29/2/2000”,输出:true .
输入:“29/2/2001”,输出:false .
这是我将如何做到这一点:
Update [2018-05-31] :如果您不关心来自其他JS上下文(外部窗口,框架或iframe)的Date对象,则可以首选这种更简单的形式:
在尝试验证日期(例如2/31/2012)时,这些答案都不适用于我(在Safari 6.0中测试),但是,当尝试任何大于31的日期时,它们工作正常 .
所以我不得不蛮力一点 . 假设日期的格式为
mm/dd/yyyy
. 我正在使用@broox答案:我的解决方案是简单地检查您是否获得了有效的日期对象:
实施
用法
你可以简单地使用moment.js
这是一个例子:
文档中的validation section非常清楚 .
而且,以下解析标志会导致无效日期:
overflow
:日期字段溢出,例如第13个月,第32个月(或非闰年2月29日),一年中第367天等 . 溢出包含指数无效单位匹配#invalidAt(见下文); -1表示没有溢出 .invalidMonth
:月份名称无效,例如片刻('Marbruary','MMMM');.包含无效的月份字符串本身,否则为null .empty
:包含无法解析的输入字符串,例如moment('this is nonsense');.布尔 .等
资料来源:http://momentjs.com/docs/
对于Angular.js项目,您可以使用:
想提一下,jQuery UI DatePicker小部件有一个非常好的日期验证器实用程序方法,它检查格式和有效性(例如,不允许01/33/2013日期) .
即使您不想将页面上的datepicker小部件用作UI元素,也可以始终将其.js库添加到您的页面,然后调用验证器方法,将要验证的值传递给它 . 为了让生活更轻松,它需要一个字符串作为输入,而不是JavaScript Date对象 .
见:http://api.jqueryui.com/datepicker/
它不是作为一种方法列出的,而是它作为一种效用函数 . 在页面中搜索“parsedate”,你会发现:
$ .datepicker.parseDate(format,value,settings) - 从具有指定格式的字符串值中提取日期 .
用法示例:
(更多信息请在http://api.jqueryui.com/datepicker/#utility-parseDate找到指定日期格式)
在上面的示例中,您将看不到警报消息,因为'01 / 03/2012'是指定格式的日历有效日期 . 但是,如果您将'stringval'等于'13 / 04/2013',则会收到警报消息,因为值'13 / 04/2013'不是日历有效的 .
如果成功解析了传入的字符串值,则'testdate'的值将是表示传入的字符串值的Javascript Date对象 . 如果没有,它将是未定义的 .
受到Borgar方法的启发,我确保代码不仅验证了日期,而且实际上确保日期是真实日期,这意味着不允许日期为31/09/2011和29/02/2011 .
好的解决方案包含在我的辅助函数库中,现在看起来像这样:
基于最高评级答案的准备功能:
您可以通过检查
Date
对象d
的有效性为了避免跨框架问题,可以用
instanceof
替换不需要在Borgar's answer中调用
getTime()
,因为isNaN()
和isFinite()
都隐式转换为数字 .我使用以下代码验证年,月和日期的值 .
有关详细信息,请参阅Check date in javascript
我结合了我发现的最佳性能结果,检查一个给定的对象:
是一个Date实例(benchmark here)
的有效日期(benchmark here)
结果如下:
这对我有用
但是这没用
一般来说,我会坚持使用浏览器堆栈中的日期植入 . 这意味着在此回复日期之前,在Chrome,Firefox和Safari中调用toDateString()时,您将始终获得"Invalid Date" .
我没有在IE中测试这个 .
你可以将你的日期和时间转换为毫秒getTime()
这
getTime()
方法无效时返回不是数字NaN