检查字符串是否为日期值

时间:2011-09-16 13:23:23

标签: javascript date-format

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

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

27 个答案:

答案 0 :(得分:200)

2015年更新

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

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

这里的大多数答案要么使用一些复杂的正则表达式,它们只匹配一些非常特定的格式并且实际上做得不正确(例如匹配1月32日,而不是像宣传的那样匹配实际的ISO日期 - 请参阅{{ 3}})他们尝试将任何内容传递给Date构造函数并希望获得最佳效果。

使用时刻

正如我在demo中解释的那样,目前有一个可用的库: this answer

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

它是12kB缩小/ gzip并在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,您可以非常具体地检查有效日期。有时候添加一些关于你期望的格式的线索是非常重要的。例如,2015年6月22日之类的日期看起来像一个有效的日期,除非您使用格式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

请参阅:Moment.js

其他图书馆

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

2016年更新

我创建了DateJS模块,它类似于(一部分)Moment但没有因现有对象的变异而导致的意外(有关详细信息,请参阅immoment)。

2018年更新

今天我建议使用the docs进行日期/时间操作而不是Moment,它(与Moment不同)使所有对象都不可变,因此没有与日期的隐式变异相关的令人讨厌的意外。

更多信息

另见:

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

底线

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

答案 1 :(得分:53)

这就是我在我正在处理的应用中解决这个问题的方法:

根据krillgar的反馈进行了更新:

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

或...

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

...

答案 2 :(得分:35)

Date.parse() 会满足吗?

查看其相对MDN Documentation page

答案 3 :(得分:20)

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

答案 4 :(得分:8)

这样的事情怎么样?它将测试它是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做一点工作你应该是好的。

答案 5 :(得分: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];
} 

答案 6 :(得分:5)

function isDate(dateStr) {
  return !isNaN(new Date(dateStr).getDate());
}
  • 这将在任何浏览器上都有效,因为它不依赖于“无效日期”检查。
  • 这将与ES6之前的旧版代码一起使用。
  • 这将在没有任何库的情况下起作用。
  • 不管日期格式如何,它都可以工作。
  • 这不依赖于Date.parse,当日期字符串中包含诸如“ Spiderman 22”之类的值时,Date.parse不能达到目的。
  • 这并不要求我们编写任何RegEx。

答案 7 :(得分:4)

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

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

答案 8 :(得分:3)

我觉得没有一个答案正确理解 OP 的要求。这里的问题是 JavaScript 可以将任何数字解析为有效日期,因为 Date 对象可以将 '3000' 之类的字符串解析为年份并返回有效的 Date 实例:

new Date('3000')

> Wed Jan 01 3000 02:00:00 GMT+0200 (Eastern European Standard Time)

为了解决这个问题,我们可以通过传入第三个参数,在严格模式下使用 Day.js 库的解析方法。它记录在他们的 String + Format 页面中。为了根据格式进行解析,我们还必须启用 CustomParseFormat 插件。我假设你可以在这里使用 ESM 导入或者设置一个像 Webpack 这样的编译器

import dayjs from 'dayjs'
import formatParser from 'dayjs/plugin/customParseFormat'

dayjs.extend(formatParser)

dayjs('3000', 'YYYY-MM-DD', true).isValid()

> false

答案 9 :(得分:3)

我会这样做

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

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

播放here

答案 10 :(得分:2)

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

如果传递的日期为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上播放here

答案 11 :(得分:2)

这是一个极简主义版本。

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

答案 12 :(得分:1)

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

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

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

答案 13 :(得分:1)

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

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

答案 14 :(得分: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;
}

答案 15 :(得分:0)

我为此创建了一个基于moment.js的解决方案,以检测ISO 8601,RFC 2822和本地格式,而无需指定解析字符串(我一直不想输入“标准”格式。)。

https://github.com/patarapolw/valid-moment

答案 16 :(得分: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;
            }
        }

答案 17 :(得分:0)

此函数验证格式为 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;
}

答案 18 :(得分:0)

尝试

<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) {
     .....
    }
})

答案 19 :(得分:0)

我知道这是一个老问题,但是我遇到了同样的问题,并且看到所有答案都无法正常工作-特别是从日期中删除数字(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"));

答案 20 :(得分:0)

在尝试了上面列出的所有答案后,我最终得到了以下内容:

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

请注意,new Date(date) !== "Invalid Date" 始终为true。希望这会有所帮助。

答案 21 :(得分:0)

检查Date对象函数是否可用于查找是否为Date对象是否正常?

喜欢

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

答案 22 :(得分:-1)

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

const checkDate = new Date(dateString);

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

答案 23 :(得分:-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

答案 24 :(得分:-1)

这有效:

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

答案 25 :(得分:-3)

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

答案 26 :(得分:-4)

试试这个:

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