检查字符串是否为日期值

IT技术 javascript date-format
2021-02-02 19:36:18

检查值是否为有效日期的简单方法是什么,允许任何已知的日期格式。

例如,我有值10-11-2009, 10/11/20092009-11-10T07:00:00+0000它们都应该被识别为日期值,而值200, 10,350不应该被识别为日期值。如果可能的话,检查这个的最简单方法是什么?因为时间戳也是允许的。

6个回答

2015年更新

这是一个老问题,但还有其他新问题,例如:

作为这个副本的副本被关闭,所以我认为在这里添加一些新信息很重要。我写它是因为我害怕人们实际上复制和粘贴这里发布的一些代码并在生产中使用它。

这里的大多数答案要么使用一些复杂的正则表达式,这些表达式只匹配一些非常特定的格式,但实际上做错了(比如匹配 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,还有其他库:

2016年更新

我创建了immomentmodule,它类似于 Moment(的子集),但没有由现有对象的突变引起的意外(有关更多信息,请参阅文档)。

2018年更新

今天,我建议使用Luxon代替 Moment 进行日期/时间操作,这(与 Moment 不同)使所有对象不可变,因此没有与日期隐式突变相关的令人讨厌的意外。

更多信息

也可以看看:

Rob Gravelle 关于 JavaScript 日期解析库的一系列文章:

底线

当然,任何人都可以尝试重新发明轮子,编写正则表达式(但在执行之前实际阅读 ISO 8601 和 RFC 3339)或使用随机数据调用内置构造函数来解析错误消息,例如'Invalid Date'(你确定这条消息是在所有平台上完全相同?在所有地区?在未来?)或者您可以使用经过测试的解决方案并花时间改进它,而不是重新发明它。这里列出的所有库都是开源的免费软件。

虽然相同,但我正在验证用户输入,但我不知道预期的日期格式......
2021-03-18 19:36:18
这可能是我在 SO 上看到的最好和维护得最好的答案
2021-03-23 19:36:18
@krivar 最好像这样使用它:moment("06/22/2015", "DD/MM/YYYY", true).isValid();明确提供预期的日期格式并带有一个true意味着严格检查的参数我用更多信息和更好的例子更新了我的答案。
2021-03-30 19:36:18
@JanVanderHaegen 如果可以假设 3/4/5 是一个有效日期,那么 2015 年 4 月 1 日也是如此,那么我建议将这些格式(可能还有更多)添加到支持格式的明确列表中。请注意,您提到的 3/4/5 在没有明确格式的情况下是不明确的。
2021-04-03 19:36:18
究竟应该如何使用它?moment("whatever 123").isValid()返回true
2021-04-10 19:36:18

这就是我在我现在正在开发的应用程序中解决这个问题的方法:

根据 krillgar 的反馈更新:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
new Date("469") 结果为 Tue Jan 01 469 00:00:00 GMT+0200 (EET)
2021-03-12 19:36:18
我需要为节点返回 (new Date(date)).toString() !== "Invalid Date"。还要注意?true : false 是多余的。在这里简单地返回表达式就足够了。
2021-03-14 19:36:18
在 IE8 中,new Date(date)不会给您“无效日期”。
2021-03-20 19:36:18
这类似于错误接受的正确答案。isDate('Mac OS X 10.14.2')在这里返回真。
2021-03-27 19:36:18
这不是一个好的答案。new Date(date) !== "Invalid Date"始终返回true,因为左表达式将返回时间值为NaN的 Date 对象,该对象永远不会是===字符串。==由于类型转换而使用“作品”。但是由于日期字符串的解析在很大程度上仍然依赖于实现,依赖它来解析随机格式我们存在严重缺陷。
2021-03-30 19:36:18

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)
抱歉@Asmor,这不是正确答案。Date.parse 将解析任何带有数字的字符串。
2021-03-14 19:36:18
另一个要小心的原因 - 数字解析为日期。Date.parse("4.3")986270400000
2021-03-22 19:36:18
Date.parse("My Name 8") 是 99662040000,这是错误的。我用过这个,现在很痛苦。
2021-03-24 19:36:18
小心这一点,因为它仍然会返回 2 月无效日期的返回值,例如:2013-02-31
2021-03-31 19:36:18
我对上面的两个“警告”案例都做了一个尝试:console.log(Date.parse("2013-02-31")); console.log(Date.parse("4.3")); 并且在这两种情况下(在 firefox 上)它都返回 NaN,所以对我来说,Date.parse 似乎没问题(无论如何,我在解析之前预先验证了破折号和正确的长度)。
2021-04-04 19:36:18

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 */
}
@FabianPicone - 好吧,从技术上讲,它有效,但与其他parse基于解决方案的共享一个缺陷Date.parse("<text here> <number here>")可能会被解析为“有效”日期,导致parsedDate无法评估为NaN.
2021-03-28 19:36:18
不起作用。如果dateFoostreet 1,则您的条件被评估为真。
2021-04-02 19:36:18
这会解析不是真实日期的类似日期的字符串,例如 2/31/2021。
2021-04-05 19:36:18
我意识到这是几年后,但isNan不是一个功能;一审不正确。
2021-04-06 19:36:18
function isDate(dateStr) {
  return !isNaN(new Date(dateStr).getDate());
}
  • 这适用于任何浏览器,因为它不依赖于“无效日期”检查。
  • 这将适用于 ES6 之前的遗留代码。
  • 这将在没有任何库的情况下工作。
  • 无论日期格式如何,这都将起作用。
  • 这不依赖于 Date.parse 当像“蜘蛛侠 22”这样的值在日期字符串中时,它会失败。
  • 这并不要求我们编写任何 RegEx。
在为一个已有 8 年历史的问题添加一个已接受的答案和 19 个现有答案时,指出您的答案解决问题的哪些新方面非常重要,否则它可能看起来是重复的答案并被删除。
2021-03-18 19:36:18
Date.parse不幸的是,关于不依赖的声明是不正确的,因为上述和Date()使用字符串函数调用构造函数几乎相同。
2021-04-08 19:36:18
你好!虽然此代码可能会解决问题,但包括解释如何以及为何解决问题将真正有助于提高您的帖子质量,并可能导致更多的投票。请记住,您是在为将来的读者回答问题,而不仅仅是现在问的人。编辑您的答案以添加解释并说明适用的限制和假设。
2021-04-09 19:36:18
我已经添加了解释。谢谢指导。
2021-04-11 19:36:18
小心,isDate('4.3') 和 isDate('xxx 8') 都返回 true
2021-04-11 19:36:18