关于javascript:检查字符串是否为日期值

Check if a string is a date value

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

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


2015更新

这是一个旧问题,但其他新问题,如:

  • 如何在JS中验证字符串是否为有效日期

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

这里的大多数答案要么使用一些复杂的正则表达式,这些表达式只匹配一些非常具体的格式,而且实际上做得不正确(例如匹配1月32日,而不匹配广告中实际的ISO日期-请参阅演示),要么尝试将任何内容传递给Date构造函数,并希望得到最好的结果。

使用力矩

正如我在这个答案中解释的,目前有一个图书馆可供使用:JS

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

它是12kb的小型/gzip,在node.js和其他地方工作:

1
2
3
4
5
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,您可以非常具体地检查有效日期。有时,添加一些关于您期望的格式的线索是非常重要的。例如,日期(如2015年6月22日)看起来像有效日期,除非您使用dd/mm/yyyy格式,在这种情况下,该日期应被视为无效日期而拒绝。有几种方法可以让您了解您期望的格式,例如:

1
2
moment("06/22/2015","MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015","DD/MM/YYYY", true).isValid(); // false

存在true参数,因此如果输入不完全符合提供的格式之一(我认为它应该是默认行为),那么现在就不会尝试解析输入。

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

1
moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

您可以使用多种格式作为数组:

1
2
3
4
5
6
7
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
  • 达特斯

2016更新

我创建了一个类似于(瞬间的一个子集)的"献祭"模块,但没有因现有对象的突变而引起的意外(有关更多信息,请参阅文档)。

2018更新

今天,我建议使用Luxon来处理日期/时间,而不是使用Moment,它(与Moment不同)使所有对象都不可变,因此没有与日期的隐式突变相关的令人不快的意外。

更多信息

参见:

  • 使用jay raj的moment.js管理日期和时间
  • 使用Bradley Holbrook的moment.js处理javascript日期

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

  • 流行的javascript日期分析库的汇总:moment.js
  • 流行的javascript日期分析库的汇总:datejs
  • 流行的javascript日期分析库的汇总:xdate

底线

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


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

根据Krillgar的反馈更新:

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

或者…

1
2
3
var isDate = function(date) {
    return (new Date(date) !=="Invalid Date" && !isNaN(new Date(date)) ) ? true : false;
}


Date.parse()足够吗?

请参见其相关MDN文档页面。


new Date(date) === 'Invalid Date'只在firefox和chrome中工作。IE8(我在我的机器上有一个用于测试)给出了NaN。

正如接受的答案所述,Date.parse(date)也适用于数字。为了解决这个问题,你也可以检查它不是一个数字(如果你想确认的话)。

1
2
3
4
5
6
7
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 */
}


像这样的怎么样?它将测试它是日期对象还是日期字符串:

1
2
3
4
5
6
7
8
9
10
11
function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

我应该提到,这并不是对iso格式的字符串进行测试,但是对regexp做更多的工作,您应该会很好。


这里的答案都不是地址检查日期是否无效,比如2月31日。此函数通过检查返回的月份是否与原始月份相等并确保提供了有效的年份来解决此问题。

1
2
3
4
5
6
7
//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];
}


我会这样做

1
2
3
4
5
6
7
8
var myDateStr= new Date("2015/5/2");

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

在这里玩耍


使用正则表达式验证它。

1
2
3
4
5
6
isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }

这是一个极简版本。

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


此可调用函数工作正常,对于有效日期返回true。请务必使用ISO格式的日期(yyyy-mm-dd或yyyy/mm/dd)进行呼叫:

1
2
3
4
5
6
7
8
9
10
11
function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}


可以使用以下答案验证日期

1
2
3
4
5
6
7
8
9
10
 var year=2019;
 var month=2;
 var date=31;
 var d = new Date(year, month - 1, date);
 if (d.getFullYear() != year
    || d.getMonth() != (month - 1)
    || d.getDate() != date) {
alert("invalid date");
return false;
}

通过引用上述所有评论,我得出了一个解决方案。

如果传递的日期是ISO格式,或者需要对其他格式进行操作,则可以使用此方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
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");
}`

你可以在这里玩钢琴


我就是这样做的。这不会涵盖所有格式。你必须做相应的调整。我对格式有控制权,所以它对我有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function isValidDate(s) {
            var dt ="";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }

是否可以检查与日期相关的函数是否可供对象查找它是否为日期对象?

喜欢

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


我知道这是一个古老的问题,但我也面临着同样的问题,我发现所有的答案都不起作用——特别是剔除日期(1200345等)的数字,这是最初的问题。这是一个我能想到的非常非正统的方法,它似乎是有效的。请指出是否有失败的情况。

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

这是删除数字的行。因此,整个函数看起来像:

1
2
3
4
5
6
7
8
9
10
11
function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false;
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() !="NaN" && tryDate !="Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));


试试这个

1
2
3
4
5
6
7
8
<input type="text" id="StartDay" value="2018/01/01" maxlength="10" />

$('#StartDay').change(function () {
    if ( ($('#StartDay').val().length == 10 && new Date($('#StartDay').val()) >= new Date("2018/01/01") &&
        (new Date($('#StartDay').val()) !=="Invalid Date") && !isNaN(new Date($('#StartDay').val()))) == false) {
     .....
    }
})

在尝试了上面列出的所有答案之后,我得出了以下结论:

1
2
3
var checkDateValue = function(date) {
    return date && (!(new Date(date) =="Invalid Date") && !isNaN(new Date(date)));
};

注意,new Date(date) !=="Invalid Date"总是正确的。希望这有帮助。


这工作:

1
2
3
var isDate = function(date) {
    return ((new Date(date)).toString() !=="Invalid Date") ? true : false;        
}


1
2
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

默认情况下,此值设置为"真"。因此,即使是格式错误的字符串也会返回良好的值。

我是这样使用的:

1
2
3
4
5
6
7
8
9
10
11
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value ="1990/13/23";

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e)
  {
    System.out.println("its bad");
  }


试试这个:

1
2
3
if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date      
}