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

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


当前回答

这里的答案都没有提到检查日期是否无效,例如2月31日。这个函数通过检查返回的月份是否等同于原来的月份,并确保提供了有效的年份来解决这个问题。

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 

其他回答

下面是可以用来验证输入是否为可以转换为日期对象的数字或字符串的方法。

它涵盖以下情况:

捕获任何导致“无效日期”日期构造函数结果的输入; 捕捉从技术角度来看日期是“有效的”,但从业务逻辑角度来看它是无效的情况,例如

new Date(null).getTime(): 0 new Date(true).getTime(): 1 new Date(-3.14).getTime(): -3 new Date(["1", "2"]).toDateString(): Tue Jan 02 2001 new Date([1,2]).toDateString(): Tue Jan 02 2001

function checkDateInputValidity(input, lowerLimit, upperLimit) {
    // make sure the input is a number or string to avoid false positive correct dates:
    if (...) {
        return false
    }
    // create the date object:
    const date = new Date(input)
    // check if the Date constructor failed:
    if (date.toDateString() === 'Invalid Date') {
        return false
    }
    // check if the Date constructor succeeded, but the result is out of range:
    if (date < new Date(lowerLimit) || date > new Date(upperLimit)) {
        return false
    }
    return true
}

// const low = '2021-12-31T23:59:59'
// const high = '2025-01-01T00:00:00'

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)或调用带有随机数据的内置构造函数来解析错误消息,如“无效日期”(你确定这条消息在所有平台上都是完全相同的吗?在所有地区?将来?)或者你可以使用一个经过测试的解决方案,花时间来改进它,而不是重新发明它。这里列出的所有库都是开源的免费软件。

下面是一个只使用Date.parse()的改进函数:

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

注意:date. parse()将解析数字:例如date. parse(1)将返回日期。这里我们检查s是不是数字,是不是日期。

以下是我如何在我现在正在开发的应用程序中解决这个问题:

根据krillgar的反馈更新:

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

是否可以检查一个日期相关的函数是可用的对象,以发现它是否是一个日期对象?

就像

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;