检查值是否为有效日期的简单方法是什么,允许任何已知的日期格式。
例如,我有值10-11-2009
, 10/11/2009
,2009-11-10T07:00:00+0000
它们都应该被识别为日期值,而值200
, 10
,350
不应该被识别为日期值。如果可能的话,检查这个的最简单方法是什么?因为时间戳也是允许的。
检查值是否为有效日期的简单方法是什么,允许任何已知的日期格式。
例如,我有值10-11-2009
, 10/11/2009
,2009-11-10T07:00:00+0000
它们都应该被识别为日期值,而值200
, 10
,350
不应该被识别为日期值。如果可能的话,检查这个的最简单方法是什么?因为时间戳也是允许的。
这是一个老问题,但还有其他新问题,例如:
作为这个副本的副本被关闭,所以我认为在这里添加一些新信息很重要。我写它是因为我害怕人们实际上复制和粘贴这里发布的一些代码并在生产中使用它。
这里的大多数答案要么使用一些复杂的正则表达式,这些表达式只匹配一些非常特定的格式,但实际上做错了(比如匹配 1 月 32 日,而不匹配所宣传的实际 ISO 日期 - 请参阅演示),或者他们尝试将任何内容传递给Date
构造函数和祝最好。
正如我在这个答案中所解释的,目前有一个可用的库: Moment.js
它是一个在 JavaScript 中解析、验证、操作和显示日期的库,它具有比标准 JavaScript 日期处理函数更丰富的 API。
它是 12kB 压缩/gzipped 并在 Node.js 和其他地方工作:
bower install moment --save # bower
npm install moment --save # npm
Install-Package Moment.js # NuGet
spm install moment --save # spm
meteor add momentjs:moment # meteor
使用 Moment,您可以非常具体地检查有效日期。有时,添加一些有关您期望的格式的线索非常重要。例如,诸如 06/22/2015 之类的日期看起来像是一个有效日期,除非您使用格式 DD/MM/YYYY,在这种情况下,应将该日期视为无效日期而拒绝。有几种方法可以告诉 Moment 您期望的格式,例如:
moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false
该true
参数是有那么瞬间将不尝试解析输入,如果它不正好符合所提供的格式之一(它应该是在我看来,一个默认的行为)。
您可以使用内部提供的格式:
moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true
您可以使用多种格式作为数组:
var formats = [
moment.ISO_8601,
"MM/DD/YYYY :) HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015 :) 13*17*21", formats, true).isValid(); // true
moment("06/22/2015 :( 13*17*21", formats, true).isValid(); // false
见:演示。
如果您不想使用 Moment.js,还有其他库:
我创建了immomentmodule,它类似于 Moment(的子集),但没有由现有对象的突变引起的意外(有关更多信息,请参阅文档)。
今天,我建议使用Luxon代替 Moment 进行日期/时间操作,这(与 Moment 不同)使所有对象不可变,因此没有与日期隐式突变相关的令人讨厌的意外。
也可以看看:
Rob Gravelle 关于 JavaScript 日期解析库的一系列文章:
当然,任何人都可以尝试重新发明轮子,编写正则表达式(但请在执行之前实际阅读 ISO 8601 和 RFC 3339)或使用随机数据调用内置构造函数来解析错误消息,例如'Invalid Date'
(你确定这条消息是在所有平台上完全相同?在所有地区?在未来?)或者您可以使用经过测试的解决方案并花时间改进它,而不是重新发明它。这里列出的所有库都是开源的免费软件。
这就是我在我现在正在开发的应用程序中解决这个问题的方法:
根据 krillgar 的反馈更新:
var isDate = function(date) {
return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
就Date.parse()
足够了?
请参阅其相关的MDN 文档页面。
Date.parse
如果字符串日期有效,则返回时间戳。以下是一些用例:
// /!\ from now (2021) date interpretation changes a lot depending on the browser
Date.parse('01 Jan 1901 00:00:00 GMT') // -2177452800000
Date.parse('01/01/2012') // 1325372400000
Date.parse('153') // NaN (firefox) -57338928561000 (chrome)
Date.parse('string') // NaN
Date.parse(1) // NaN (firefox) 978303600000 (chrome)
Date.parse(1000) // -30610224000000 from 1000 it seems to be treated as year
Date.parse(1000, 12, 12) // -30610224000000 but days and month are not taken in account like in new Date(year, month,day...)
Date.parse(new Date(1970, 1, 0)) // 2588400000
// update with edge cases from comments
Date.parse('4.3') // NaN (firefox) 986248800000 (chrome)
Date.parse('2013-02-31') // NaN (firefox) 1362268800000 (chrome)
Date.parse("My Name 8") // NaN (firefox) 996616800000 (chrome)
new Date(date) === 'Invalid Date'
仅适用于 Firefox 和 Chrome。IE8(我在我的机器上用于测试目的的那个)给出 NaN。
正如接受的答案所述,Date.parse(date)
也适用于数字。因此,为了解决这个问题,您还可以检查它是否不是数字(如果您想确认的话)。
var parsedDate = Date.parse(date);
// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
/* do your work */
}
function isDate(dateStr) {
return !isNaN(new Date(dateStr).getDate());
}