检查字符串是否为日期值


207

检查值是否为有效日期(允许使用任何已知的日期格式)的简便方法是什么。

比如我有值10-11-200910/11/20092009-11-10T07:00:00+0000它都应该被视为日期值,和值20010350,不应被视为一个日期值。如果可能的话,最简单的检查方法是什么?因为时间戳也将被允许。


Answers:


42

Date.parse()足够了?

请参阅其相对的MDN文档页面


24
请注意这一点,因为它仍会返回2月份无效日期的返回值,例如:2013-02-31
leojh 2013年

58
注意的另一个原因-数字解析为日期。Date.parse("4.3")986270400000
Mogsdad

我尝试了上述两种“注意”情况的小提琴:console.log(Date.parse(“ 2013-02-31”)); console.log(Date.parse(“ 4.3”)); 在这两种情况下(在Firefox上)它都返回NaN,所以对我而言,Date.parse似乎还可以(我正在对破折号和正确的长度进行预验证,无论如何在解析之前)。
Cloudranger

55
抱歉,@ Asmor,这不是正确的答案。Date.parse将解析了一些它的任何字符串。
jwerre

11
Date.parse(“我的名字8”)作为99662040000来了,这是错误的。我用了这个,现在痛苦了。
罗伊斯(Rohith)

250

2015年更新

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

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

此处的大多数答案要么使用一些仅匹配某些非常特定格式的复杂正则表达式,然后实际执行不正确(例如匹配1月32日,而不匹配所宣传的实际ISO日期-参见demo),要么尝试将任何内容传递给Date构造函数并希望最好。

使用时刻

正如我在此答案中解释的那样,当前有一个可用的库: Moment.js

它是一个用于解析,验证,操作和显示JavaScript中的日期的库,它具有比标准JavaScript日期处理功能丰富的API。

它缩小/压缩了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

true参数存在,因此,如果矩不完全符合所提供的一种格式,则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

请参阅:DEMO

其他图书馆

如果您不想使用Moment.js,那么还有其他库:

2016更新

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

2018更新

今天,我建议使用Luxon代替Moment 来进行日期/时间操作(与Moment不同),Moment使所有对象不可变,因此不会出现与隐式更改日期有关的令人讨厌的惊喜。

更多信息

也可以看看:

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

底线

当然,任何人都可以尝试重新发明轮子,编写正则表达式(但在执行此操作之前请先阅读ISO 8601和RFC 3339)或使用随机数据调用buit-in构造函数以解析错误消息,例如'Invalid Date'(确定此消息是在所有平台上都完全相同(在所有语言环境中还是在将来?),或者您可以使用经过测试的解决方案并花费时间来改进它,而不是重新发明它。此处列出的所有库都是开源的免费软件。


4
究竟应该如何使用呢?moment("whatever 123").isValid()返回true
krivar

4
@krivar最好像这样使用它:moment("06/22/2015", "DD/MM/YYYY", true).isValid();显式提供预期的日期格式,并带有true表示严格检查的参数。我使用更多信息和更好的示例更新了我的答案。
rsp 2015年

2
虽然相同,但是我正在验证用户输入,但我不知道预期的日期格式……
Jan Van der Haegen

3
@JanVanderHaegen如果可以假设3/4/5是有效日期,那么也可以假设是2015年4月1日,那么我建议将这些格式(可能更多)添加到受支持格式的明确列表中。请注意,您提到的3/4/5在没有显式格式的情况下是模棱两可的。
rsp

3
这可能是我在SO上看到的最好且维护得最好的答案
Phil3992 '18

62

这就是我现在正在使用的应用程序中解决此问题的方式:

根据来自磷虾的反馈进行了更新:

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

5
我需要返回(new Date(date))。toString()!==“无效日期”为节点。还要注意吗?true:false是多余的。只需返回表达式就可以了。
domenukk 2014年

在IE8中,new Date(date)不会给您“无效日期”。
krillgar 2014年

13
这不是一个好答案。new Date(date) !== "Invalid Date"始终返回true,因为左表达式将返回一个时间值为NaN的Date对象,该值永远不能===为字符串。==由于类型转换而使用“作品”。但是由于日期字符串的解析在很大程度上仍依赖于实现,因此依靠它来解析随机格式存在严重缺陷。
RobG 2015年

4
new Date(“ 469”)的结果为1月01日469 00:00:00 GMT + 0200(EET)
Dan Ochiana

3
这类似于被错误接受的正确答案。isDate('Mac OS X 10.14.2')在这里返回true。
BradStell

24

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 */
}

2
我意识到这是几年后的事,但isNan不是功能。一审案件不正确。
蒂姆·刘易斯

不起作用。如果dateFoostreet 1,则您的条件为真。
Fabian Picone

9

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

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进行更多工作后,您应该会很满意。


7

此处没有答案可以检查日期是否无效,例如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];
} 

因为问题不是要检查字符串是否是“有效”日期,而是要检查字符串是否代表日期格式。
Thizzer

@Thizzer好点。我不介意解决问题,但是在重读您的问题时,我很沮丧,因为您说不应验证10,但应该允许使用时间戳。
ykay说恢复莫妮卡

xD甚至都没有注意到,这是我早些时候关于日期/时间戳的问题。我将在今天晚些时候尝试编辑问题。
Thizzer '16

为什么是第1个月然后是第+1月?
卡皮尔·拉格万希

@KapilRaghuwanshi javascript日期使用从零开始的月份,因此您需要减去1以创建正确的日期,然后添加1以检查其是否与原始月份相同
ykay说,恢复莫妮卡

5

使用正则表达式进行验证。

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);
    }

4

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

如果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。


1
该解决方案对我来说最有效,因为我的应用程序支持的日期字符串的格式为YYYY-MM-DD,因此附加T00:00:00.000Z并使用此解决方案来检查有效字符串很简单。
加速

对于JavaScript这是正常的,但是如何在打字稿中使用它呢?

3

这是仅使用的改进功能Date.parse()

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

注意: Date.parse()将解析数字:例如Date.parse(1)将返回一个日期。因此,在这里我们检查是否s不是数字,如果是日期。


1
这不起作用,因为通过“测试2”将作为真实日期通过。在最新版的chrome中进行了测试
user1751287

2

我会这样做

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

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

在这里


2
在当前的Chrome(可能是其他浏览器)中,此功能不起作用。我更改了提供给的字符串,EXAMPLE STRING 12345并返回“有效日期”。

1

这是一个简约的版本。

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

1
对于我的示例仍然不起作用:isDate("  1")
Tomas

@Tom在确定是否为日期之前,应检查该值是否包含空格字符。您的问题是一种特殊情况,需要由控制器逻辑处理。
Polywhirl先生17年

1
不需要检查空格字符,因为字符串2020年1月1日是包含空格的有效日期。您的方法不能解决这个问题。
Kirstin Walsh

1

此可调用函数可以完美运行,为有效日期返回true。请务必使用ISO格式的日期(yyyy-mm-dd或yyyy / mm / dd)进行呼叫:

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
很好,但是并不能完全回答问题。具体来说,它不适用于“ 2009-11-10T07:00:00 + 0000”(给出的示例之一)。
amadan's

不要认为这可行,因为它应该validateDate('2016-12-30T08:00:00.000Z')//否
Jose Browne

无论此方法是否有效,都可以简化为return !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung

1

我知道这是一个古老的问题,但是我遇到了同样的问题,并且发现没有一个答案能正常工作-特别是从日期中删除数字(1,200,345等),这是原始问题。这是我可以想到的一种非常不合常规的方法,并且似乎可行。请指出是否有失败的情况。

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

这是清除数字的行。因此,整个功能可能类似于:

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
console.log("hello 1 ", isDate("hello 1 "));返回true
约翰

你是对的!你有解决方案吗?到目前为止,我认为这里没有任何答案可以真正解决问题!
peekolo '19

“ 100%”(百分比)返回true
toddmo

0

检查与日期相关的函数是否可用于该对象以找到它是否为Date对象,是否可以?

喜欢

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

0

这就是我最终要这样做的方式。这不会涵盖所有格式。您必须进行相应的调整。我可以控制格式,所以对我有用

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

好的,这是一个古老的问题,但是我在这里查看解决方案时找到了另一个解决方案。对我来说,要检查日期对象是否存在getTime()函数:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

一个轻量级的库已经为您准备好:Day.js


这基本上是在StackOverflow上做广告,请不要这样做。
c4sh

-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

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

我用过这样的东西:

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");
  }

5
... javascript ?!
artparks 16-10-28

-5

试试这个:

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

6
这对我不起作用。首先,条件中的var不会解析,但是如果您将其删除,然后尝试如下操作:if(date = new Date(“ rubbish”)){alert(date); }即使日期是垃圾,该警报仍将执行,因为Date函数将返回“无效日期”(至少在firefox上),因此条件的评估结果为true。我想如果某些浏览器在无效日期返回null,那么它将在那些浏览器上正常工作。此处可能存在浏览器不一致。
Cloudranger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.