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

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


当前回答

2015年更新

这是一个老问题,但其他一些新问题,比如:

如何验证如果一个字符串是一个有效的日期在js

所以我认为在这里添加一些新的信息是很重要的。我写它是因为我害怕人们会复制粘贴这里发布的一些代码并在生产中使用它。

这里的大多数答案要么使用一些复杂的正则表达式,只匹配一些非常特定的格式,实际上做得不正确(比如匹配1月32日,而不匹配实际的ISO日期,如广告-见演示),或者他们试图将任何东西传递给日期构造函数,并希望得到最好的结果。

使用的时刻

正如我在回答中解释的,目前有一个库可以用于此: Moment.js

它是一个用JavaScript解析、验证、操作和显示日期的库,它的API比标准的JavaScript日期处理函数丰富得多。

它是12kB的压缩文件,可以在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

真正的参数是这样的,如果输入不完全符合所提供的格式之一,Moment将不会尝试解析输入(在我看来,这应该是默认行为)。

你可以使用内部提供的格式:

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,还有其他库:

XDate DateJS

2016年更新

我创建了immoment模块,它就像(一个子集)Moment,但没有由现有对象的突变引起的惊喜(更多信息请参阅文档)。

2018年更新

今天,我推荐使用Luxon进行日期/时间操作,而不是Moment,它(与Moment不同)使所有对象都是不可变的,因此不会出现与日期隐式突变相关的令人讨厌的意外。

更多信息

参见:

使用Moment.js管理日期和时间 使用Bradley Holbrook的Moment.js处理JavaScript日期

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

流行的JavaScript日期解析库综述:Moment.js 流行的JavaScript日期解析库综述:Datejs 流行JavaScript日期解析库综述:XDate

底线

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

其他回答

我会这样做

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

在这里玩耍

通过参考以上所有的评论,我已经找到了一个解决方案。

如果传递的日期是ISO格式或需要为其他格式操作,则此方法有效。

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

你可以在JSFiddle上玩。

这是一个极简的版本。

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

该函数验证格式为m/d/yyyy或mm/dd/yyyy的输入字符串是否可以转换为日期,并且该日期是与输入字符串匹配的有效日期。添加更多条件检查来验证其他格式。

/**
 * Verify if a string is a date
 * @param {string} sDate - string that should be formatted m/d/yyyy or mm/dd/yyyy
 * @return {boolean} whether string is a valid date
 */
function isValidDate(sDate) {
  let newDate = new Date(sDate);
  console.log(sDate + " date conversion: " + newDate);
  let isDate = (!isNaN(newDate.getTime()));
  console.log(sDate + " is a date: " + isDate);
  if (isDate) {
    let firstSlash = sDate.indexOf("/");
    let secondSlash = sDate.indexOf("/",firstSlash+1);
    let originalDateString = parseInt(sDate.slice(0,firstSlash),10) + "/" + parseInt(sDate.slice(firstSlash+1,secondSlash),10) + "/" + parseInt(sDate.slice(secondSlash+1),10);
    let newDateString = (newDate.getMonth()+1) + "/" + (newDate.getDate()) + "/" + (newDate.getFullYear());
    isDate = (originalDateString == newDateString);
    console.log(originalDateString + " matches " + newDateString + ": " + isDate);
  }
  return isDate;
}

我知道这是一个老问题,但我遇到了同样的问题,发现没有一个答案能正常工作——特别是从日期中剔除数字(1,200,345等),这是最初的问题。这是我能想到的一个相当非正统的方法,它似乎有效。请指出是否有失败的情况。

if(sDate.toString() == parseInt(sDate).toString()) return false;

这一行是用来剔除数字的。因此,整个函数看起来像这样:

功能障碍(sDate) ( 如果(sDate.toString() == parseInt(sDate).toString()假返回; var tryDate =新日期(sDate); 回归(tryDate & tryDate.toString !=“NaN”& tryDate !=“Invalid Date”); ) 游戏机。log (" 100 ", isDate (100); 游戏机。log(“234”isDate(“234”); 游戏机。log (, isDate "你好"()"你好"); log控制台(“2018年2月25日”,“2018年2月25日”); 游戏机。log (2009-11-10T07:00:00 + 2”、“isDate(“2009-11-10T07:00:00 + 2”));