在JavaScript中检测“无效日期”Date实例

我想告诉JS中有效和无效日期对象之间的区别,但无法弄清楚如何:

var d = new Date("foo");console.log(d.toString()); // shows 'Invalid Date'console.log(typeof d); // shows 'object'console.log(d instanceof Date); // shows 'true'

对于编写isValidDate函数有什么想法吗?

  • Ash推荐Date.parse用于解析日期字符串,它提供了一种权威的方法来检查日期字符串是否有效。
  • 如果可能的话,我更喜欢让我的API接受Date实例并能够检查/断言它是否有效。Borgar的解决方案可以做到这一点,但我需要跨浏览器测试它。我也想知道是否有更优雅的方法。
  • Ash让我考虑让我的API根本不接受Date实例,这将是最容易验证的。
  • Borgar建议测试Date实例,然后测试Date的时间值。如果日期无效,则时间值为NaN。我检查了ECMA-262,此行为符合标准,这正是我正在寻找的。
1321637 次浏览

而不是使用new Date(),你应该使用:

var timestamp = Date.parse('foo');
if (isNaN(timestamp) == false) {var d = new Date(timestamp);}

Date.parse()返回一个时间戳,一个表示自01/Jan/1970以来的毫秒数的整数。如果无法解析提供的日期字符串,它将返回NaN

我是这样做的:

if (Object.prototype.toString.call(d) === "[object Date]") {// it is a dateif (isNaN(d)) { // d.getTime() or d.valueOf() will also work// date object is not valid} else {// date object is valid}} else {// not a date object}

更新[2018-05-31]:如果您不关心来自其他JS上下文(外部窗口、框架或iFramework)的Date对象,则可能首选这种更简单的形式:

function isValidDate(d) {return d instanceof Date && !isNaN(d);}

更新时间[2021-02-01]:请注意,“无效日期”(2013-13-32)和“无效日期对象”(new Date('foo'))之间存在根本区别。这个答案不要处理验证日期输入,仅当Date实例有效时。

您可以通过以下方式检查Date对象d的有效性

d instanceof Date && isFinite(d)

为了避免跨帧问题,可以将instanceof检查替换为

Object.prototype.toString.call(d) === '[object Date]'

Borgar的回答中调用getTime()是不必要的,因为isNaN()isFinite()都隐式转换为数字。

我真的很喜欢克里斯托夫的方法(但没有足够的声誉来投票)。为了我的使用,我知道我总是有一个Date对象,所以我只是用一个有效的()方法扩展了date。

Date.prototype.valid = function() {return isFinite(this);}

现在我可以写这个,它比仅仅检查代码中的isFinite更具描述性…

d = new Date(userDate);if (d.valid()) { /* do stuff */ }

我基于Borgar的解决方案编写了以下解决方案。包含在我的辅助函数库中,现在看起来像这样:

Object.isDate = function(obj) {/// <summary>/// Determines if the passed object is an instance of Date./// </summary>/// <param name="obj">The object to test.</param>
return Object.prototype.toString.call(obj) === '[object Date]';}
Object.isValidDate = function(obj) {/// <summary>/// Determines if the passed object is a Date object, containing an actual date./// </summary>/// <param name="obj">The object to test.</param>
return Object.isDate(obj) && !isNaN(obj.getTime());}
// check whether date is validvar t = new Date('2011-07-07T11:20:00.000+00:00x');valid = !isNaN(t.valueOf());

我认为这是一个漫长的过程。我们可以缩短它,如下所示:

 function isValidDate(dateString) {debugger;var dateStringSplit;var formatDate;
if (dateString.length >= 8 && dateString.length<=10) {try {dateStringSplit = dateString.split('/');var date = new Date();date.setYear(parseInt(dateStringSplit[2]), 10);date.setMonth(parseInt(dateStringSplit[0], 10) - 1);date.setDate(parseInt(dateStringSplit[1], 10));
if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {return true;}else {return false;}
} catch (e) {return false;}}return false;}

Borgar的方法的启发,我确保代码不仅验证日期,而且实际上确保日期是真实日期,这意味着不允许31/09/2011和29/02/2011这样的日期。

function(dateStr) {s = dateStr.split('/');d = new Date(+s[2], s[1] - 1, +s[0]);if (Object.prototype.toString.call(d) === "[object Date]") {if (!isNaN(d.getTime()) && d.getDate() == s[0] &&d.getMonth() == (s[1] - 1)) {return true;}}return "Invalid date!";}

我使用以下代码来验证年、月和日期的值。

function createDate(year, month, _date) {var d = new Date(year, month, _date);if (d.getFullYear() != year|| d.getMonth() != month|| d.getDate() != _date) {throw "invalid date";}return d;}

有关详细信息,请参阅在javascript中检查日期

您可以检查txDate.value的有效格式与此程序.如果它是在不正确的格式的日期objct不实例化和返回null到dt.

 var dt = new Date(txtDate.value)if (isNaN(dt))

正如@MiF在短时间内建议的那样

 if(isNaN(new Date(...)))

上述解决方案都不适用于我,但有效的是

function validDate (d) {var date = new Date(d);var day = "" + date.getDate();if ( day.length == 1 ) day = "0" + day;var month = "" + (date.getMonth() + 1);if ( month.length == 1 ) month = "0" + month;var year = "" + date.getFullYear();return (( month + "/" + day + "/" + year ) == d );}

上面的代码将看到当JS将02/31/2012变为03/02/2012时它无效

在尝试验证日期(如2/31/2012)时,这些答案都不适用于我(在Safari6.0中进行了测试),但是,在尝试任何大于31的日期时,它们都可以正常工作。

所以我不得不有点蛮力。假设日期是格式mm/dd/yyyy。我使用@broox回答:

Date.prototype.valid = function() {return isFinite(this);}
function validStringDate(value){var d = new Date(value);return d.valid() && value.split('/')[0] == (d.getMonth()+1);}
validStringDate("2/29/2012"); // true (leap year)validStringDate("2/29/2013"); // falsevalidStringDate("2/30/2012"); // false

我的解决方案是简单地检查你是否得到一个有效的日期对象:

实施

Date.prototype.isValid = function () {// An invalid date object returns NaN for getTime() and NaN is the only// object not strictly equal to itself.return this.getTime() === this.getTime();};

用法

var d = new Date("lol");
console.log(d.isValid()); // false
d = new Date("2012/09/11");
console.log(d.isValid()); // true
IsValidDate: function(date) {var regex = /\d{1,2}\/\d{1,2}\/\d{4}/;if (!regex.test(date)) return false;var day = Number(date.split("/")[1]);date = new Date(date);if (date && date.getDate() != day) return false;return true;}

我想提一下jQuery UI DatePicker小部件有一个非常好的日期验证器实用程序方法,可以检查格式和有效性(例如,不允许01/33/2013日期)。

即使您不想将页面上的datepicker小部件用作UI元素,您也可以始终将其. js库添加到您的页面,然后调用validator方法,将您想要验证的值传递给它。为了让生活更轻松,它采用字符串作为输入,而不是JavaScript Date对象。

见:http://api.jqueryui.com/datepicker/

它没有作为方法列出,但它存在-作为实用函数。在页面中搜索“parsedate”,您会发现:

$.datepicker.parse日期(格式、值、设置)-从具有指定格式的字符串值中提取日期。

示例用法:

var stringval = '01/03/2012';var testdate;
try {testdate = $.datepicker.parseDate('mm/dd/yy', stringval);// Notice 'yy' indicates a 4-digit year value} catch (e){alert(stringval + ' is not valid.  Format must be MM/DD/YYYY ' +'and the date value must be valid for the calendar.';}

(更多关于指定日期格式的信息可以在http://api.jqueryui.com/datepicker/#utility-parseDate找到)

在上面的示例中,您不会看到警报消息,因为'01/03/2012'是指定格式的日历有效日期。但是,如果您使'stringval'等于'13/04/2013',例如,您会收到警报消息,因为值'13/04/2013'不是日历有效的。

如果传入的字符串值被成功解析,'testdate'的值将是一个Javascript Date对象,表示传入的字符串值。如果不是,它将是未定义的。

Date对象到string是检测两个字段是否为有效日期的更简单可靠的方法。例如:如果您输入此 "-------" 日期输入字段。上面的一些答案将不起作用。

jQuery.validator.addMethod("greaterThan",
function(value, element, params) {var startDate = new Date($(params).val());var endDate = new Date(value);
if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {return false;} else {return endDate > startDate;}},'Must be greater than {0}.');

您可以简单地使用moment.js

下面是一个例子:

var m = moment('2015-11-32', 'YYYY-MM-DD');m.isValid(); // false

留档中的验证部分非常清晰。

此外,以下解析标志会导致无效日期:

  • overflow:日期字段的溢出,例如第13个月,该月的第32天(或非闰年的2月29日),一年中的第367天等,溢出包含匹配的无效单位的索引(见下文);-1表示没有溢出。
  • invalidMonth:一个无效的月份名称,例如时刻('Mar的','MMMM');。包含无效的月份字符串本身,否则为null。
  • empty:一个输入字符串,不包含任何可解析的内容,例如时刻('this is无稽之谈');。布尔值。
  • 等等。

来源:http://momentjs.com/docs/

对于日期的基于int 1的组件:

var is_valid_date = function(year, month, day) {var d = new Date(year, month - 1, day);return d.getFullYear() === year && (d.getMonth() + 1) === month && d.getDate() === day};

测试:

    is_valid_date(2013, 02, 28)&&  is_valid_date(2016, 02, 29)&& !is_valid_date(2013, 02, 29)&& !is_valid_date(0000, 00, 00)&& !is_valid_date(2013, 14, 01)

您可以将日期和时间转换为毫秒获取时间

这个getTime()方法在无效时返回不是数字NaN

if(!isNaN(new Date("2012/25/255").getTime()))return 'valid date time';return 'Not a valid date time';

这招对我很管用

new Date('foo') == 'Invalid Date'; //is true

然而这并没有奏效

new Date('foo') === 'Invalid Date'; //is false
var isDate_ = function(input) {var status = false;if (!input || input.length <= 0) {status = false;} else {var result = new Date(input);if (result == 'Invalid Date') {status = false;} else {status = true;}}return status;}

我已经编写了这个函数。传递一个字符串参数,它将根据这种格式“dd/MM/yyyy”确定它是否是有效日期。

这是一个测试

输入:“哈哈哈”,输出:false。

输入:"29/2/2000",输出:true。

输入:"29/2/2001",输出:false。

function isValidDate(str) {var parts = str.split('/');if (parts.length < 3)return false;else {var day = parseInt(parts[0]);var month = parseInt(parts[1]);var year = parseInt(parts[2]);if (isNaN(day) || isNaN(month) || isNaN(year)) {return false;}if (day < 1 || year < 1)return false;if(month>12||month<1)return false;if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)return false;if ((month == 4 || month == 6 || month == 9 || month == 11 ) && day > 30)return false;if (month == 2) {if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0 && (year % 100) == 0)) {if (day > 29)return false;} else {if (day > 28)return false;}}return true;}}

所选的答案非常好,我也在使用它。但是,如果您正在寻找一种验证用户日期输入的方法,您应该注意Date对象非常持久地将看似无效的构造参数转换为有效参数。以下单元测试代码说明了这一点:

QUnit.test( "valid date test", function( assert ) {//The following are counter-examples showing how the Date object will//wrangle several 'bad' dates into a valid date anywayassert.equal(isValidDate(new Date(1980, 12, 15)), true);d = new Date();d.setFullYear(1980);d.setMonth(1);d.setDate(33);assert.equal(isValidDate(d), true);assert.equal(isValidDate(new Date(1980, 100, 150)), true);//If you go to this exterme, then the checker will failassert.equal(isValidDate(new Date("This is junk")), false);//This is a valid date stringassert.equal(isValidDate(new Date("November 17, 1989")), true);//but is this?assert.equal(isValidDate(new Date("November 35, 1989")), false);//Ha!  It's not.  So, the secret to working with this version of//isValidDate is to pass in dates as text strings... Hooboy//alert(d.toString());});

我结合了我在检查给定对象时发现的最佳性能结果:

结果如下:

function isValidDate(input) {if(!(input && input.getTimezoneOffset && input.setUTCFullYear))return false;
var time = input.getTime();return time === time;};

此函数验证以字符分隔的数字格式的字符串日期,例如dd/mm/yyyy、mm/dd/yyyy

/*Param  :1)the date in string data type2)[optional - string - default is "/"] the date delimiter, most likely "/" or "-"3)[optional - int - default is 0] the position of the day component when the date string is broken up via the String.split function (into arrays)4)[optional - int - default is 1] the position of the month component when the date string is broken up via the String.split function (into arrays)5)[optional - int - default is 2] the position of the year component when the date string is broken up via the String.split function (into arrays)
Return : a javascript date is returned if the params are OK else null*/function IsValidDate(strDate, strDelimiter, iDayPosInArray, iMonthPosInArray, iYearPosInArray) {var strDateArr; //a string array to hold constituents day, month, and year componentsvar dtDate; //our internal converted datevar iDay, iMonth, iYear;

//sanity check//no integer checks are performed on day, month, and year tokens as parsing them below will result in NaN if they're invalidif (null == strDate || typeof strDate != "string")return null;
//defaultsstrDelimiter = strDelimiter || "/";iDayPosInArray = undefined == iDayPosInArray ? 0 : iDayPosInArray;iMonthPosInArray = undefined == iMonthPosInArray ? 1 : iMonthPosInArray;iYearPosInArray = undefined == iYearPosInArray ? 2 : iYearPosInArray;
strDateArr = strDate.split(strDelimiter);
iDay = parseInt(strDateArr[iDayPosInArray],10);iMonth = parseInt(strDateArr[iMonthPosInArray],10) - 1; // Note: months are 0-basediYear = parseInt(strDateArr[iYearPosInArray],10);
dtDate = new Date(iYear,iMonth, // Note: months are 0-basediDay);
return (!isNaN(dtDate) && dtDate.getFullYear() == iYear && dtDate.getMonth() == iMonth && dtDate.getDate() == iDay) ? dtDate : null; // Note: months are 0-based}

示例调用:

var strDate="18-01-1971";
if (null == IsValidDate(strDate)) {
alert("invalid date");}

通常我会坚持使用浏览器堆栈中的任何日期植入。这意味着在Chrome、Firefox和Safari中调用toDateString()获取时间戳时,您将始终获得“无效日期”。

if(!Date.prototype.isValidDate){Date.prototype.isValidDate = function(){return this.toDateString().toLowerCase().lastIndexOf('invalid') == -1;};}

但我没有在IE中测试它。

function isValidDate(date) {return !! (Object.prototype.toString.call(date) === "[object Date]" && +date);}
function isValidDate(strDate) {var myDateStr= new Date(strDate);if( ! isNaN ( myDateStr.getMonth() ) ) {return true;}return false;}

像这样叫它

isValidDate(""2015/5/2""); // => trueisValidDate(""2015/5/2a""); // => false

对于Angular.js项目,您可以使用:

angular.isDate(myDate);

这种风格的isValidDate使用处理闰年的正则表达式。它适用于常规日期,但不适用于iso日期:

function isValidDate(value) {return /((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(29)([/])([2468][048]00)$)|(^(0?2)([/])(29)([/])([3579][26]00)$)|(^(0?2)([/])(29)([/])([1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)|(^(0?2)([/])(29)([/])([2-9][0-9][2468][048])$)|(^(0?2)([/])(29)([/])([1][89][13579][26])$)|(^(0?2)([/])(29)([/])([2-9][0-9][13579][26])$))/.test(value)}
function test(value) {console.log(`${value} valid: ${isValidDate(value)}`)}
<button onClick="test('foo')">foo</button><button onClick="test('2/20/2000')">2/20/2000</button><button onClick="test('20/2/2000')">20/2/2000</button><button onClick="test('2022-02-02T18:51:53.517Z')">2022-02-02T18:51:53.517Z</button>

检查有效日期的最短答案

if(!isNaN(date.getTime()))
Date.valid = function(str){var d = new Date(str);return (Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()));}

https://gist.github.com/dustinpoissant/b83750d8671f10c414b346b16e290ecf

基于顶级答案的就绪函数:

  /*** Check if date exists and is valid.** @param {String} dateString Date in YYYY-mm-dd format.*/function isValidDate(dateString) {var isValid = false;var date;
date =new Date(dateString);
if (Object.prototype.toString.call(date) === "[object Date]") {
if (isNaN(date.getTime())) {
// Date is unreal.
} else {// Date is real if month and day match each other in date and string (otherwise may be shifted):isValid =date.getUTCMonth() + 1 === dateString.split("-")[1] * 1 &&date.getUTCDate() === dateString.split("-")[2] * 1;}} else {// It's not a date.}
return isValid;}

只需要date.parse(valueToBeTested) > 0即可。有效的日期将返回时代值,无效的值将返回NaN,这将因甚至不是数字而无法通过> 0测试。

这是如此简单,以至于帮助函数不会保存代码,尽管它可能更具可读性。如果你想要一个:

String.prototype.isDate = function() {return !Number.isNaN(Date.parse(this));}

要使用:

"StringToTest".isDate();

所以我喜欢@问克拉克的答案,但没有什么改进,它为不能通过var d=new Date(d)的日期添加了try cat块-

function checkIfDateNotValid(d) {try{var d = new Date(d);return !(d.getTime() === d.getTime()); //NAN is the only type which is not equal to itself.}catch (e){return true;}
}

这里已经有太多复杂的答案了,但简单的一行就足够了(ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

在ES6中:

Date.prototype.isValid = d => !isNaN(Date.parse(d));

Date.prototype.toISOString在无效日期抛出RangeError(至少在Chromium和Firefox中)。您可以将其用作验证手段,可能不需要isValidDate本身(EAFP)。否则它是:

function isValidDate(d){try{d.toISOString();return true;}catch(ex){return false;}}

我已经看到了一些非常接近这个小片段的答案。

JavaScript方式:

function isValidDate(dateObject){return new Date(dateObject).toString() !== 'Invalid Date';}console.log(isValidDate('WTH')); // -> falseconsole.log(isValidDate(new Date('WTH'))); // -> falseconsole.log(isValidDate(new Date())); // -> true

ES2015方式:

const isValidDate = dateObject => new Date(dateObject).toString() !== 'Invalid Date';console.log(isValidDate('WTH')); // -> falseconsole.log(isValidDate(new Date('WTH'))); // -> falseconsole.log(isValidDate(new Date())); // -> true

还有另一种检查日期是否为有效日期对象的方法:

const isValidDate = (date) =>typeof date === 'object' &&typeof date.getTime === 'function' &&!isNaN(date.getTime())

简单而优雅的解决方案:

const date = new Date(`${year}-${month}-${day} 00:00`)const isValidDate = (Boolean(+date) && date.getDate() == day)

来源:

[1]https://medium.com/@esganzerla

[2]JavaScript中new Date()中显示的日期不正确

试试这样的东西:

if (!('null' === JSON.stringify(new Date('wrong date')))) console.log('correct');else console.log('wrong');

如果您使用io-ts,则可以直接使用解码器创建日期

import { DateFromISOString } from 'io-ts-types/lib/DateFromISOString'
const decoded = DateFromISOString.decode('2020-05-13T09:10:50.957Z')

还没有人提到它,所以符号也是一种方法:

Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date") // true
Symbol.for(new Date()) === Symbol.for("Invalid Date") // false

console.log('Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")', Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")) // true
console.log('Symbol.for(new Date()) === Symbol.for("Invalid Date")', Symbol.for(new Date()) === Symbol.for("Invalid Date")) // false

注意:https://caniuse.com/#search=Symbol

纯JavaScript解决方案:

const date = new Date(year, (+month-1), day);const isValidDate = (Boolean(+date) && date.getDate() == day);

也适用于闰年!

信用https://medium.com/@esganzerla

为什么我建议moment.js

这是个很受欢迎的图书馆

简单解决所有日期和时间,格式,时区问题

易于检查字符串日期有效与否

var date = moment("2016-10-19");date.isValid()

我们不能用简单的方法来验证所有的案例

部署

如果我插入像89,90,95这样的有效数字new Date()上面的几个answare,我得到了不好的结果,但它返回true

const isValidDate = date => {console.log('input'+date)var date=new Date(date);
console.log(date)return !! (Object.prototype.toString.call(date) === "[object Date]" && +date)//return !isNaN(date.getTime())}

var test="05/04/2012"console.log(isValidDate(test))


var test="95"console.log(isValidDate(test))


var test="89"console.log(isValidDate(test))


var test="80"console.log(isValidDate(test))


var test="badstring"console.log(isValidDate(test))

我有一个解决办法。

const isInvalidDate = (dateString) => JSON.stringify(new Date(dateString)) === 'null';
const invalidDate = new Date('Hello');console.log(isInvalidDate(invalidDate)); //true
const validDate = new Date('2021/02/08');console.log(isInvalidDate(validDate)); //false

为什么在我之前尝试了这么多之后,我要写第48个答案?大多数答案都是部分正确的,并不适用于所有情况,而其他答案则不必要地冗长和复杂。下面是一个非常简洁的解决方案。这将检查它是否是Date类型,然后检查它是否是有效的日期对象:

return x instanceof Date && !!x.getDate();

现在用于解析日期文本:大多数解决方案使用Date.parse()或“new Date()”--这两个将失败某些情况下可以是危险的。JavaScript解析各种格式,并且依赖于本地化。例如,“1”和“blah-123”等字符串将解析为有效日期。

还有一些帖子要么使用大量代码,要么使用一英里长的RegEx,要么使用第三方框架。

这是验证日期字符串的简单方法。

function isDate(txt) {var matches = txt.match(/^\d?\d\/(\d?\d)\/\d{4}$/); //Note: "Day" in the RegEx is parenthesizedreturn !!matches && !!Date.parse(txt) && new Date(txt).getDate()==matches[1];}
TEST THE FUNCTION<br /><br /><input id="dt" value = "12/21/2020"><input type="button" value="validate" id="btnAction" onclick="document.getElementById('rslt').innerText = isDate(document.getElementById('dt').value)"><br /><br />Result: <span id="rslt"></span>

isDate的第一行使用简单的RegEx解析输入文本,以验证日期格式mm/dd/yyyy或m/d/yyyy。对于其他格式,您需要相应地更改RegEx,例如对于dd-mm-yyyy,RegEx变为/^(\d?\d)-\d?\d-\d{4}$/

如果解析失败,“匹配”为空,否则它存储月份的日期。第二行进行更多测试以确保它是有效日期,并消除像2021年9月31日这样的情况(JavaScript允许)。最后注意双重打击(!!)将“false sy”转换为布尔假。

当一个人可以不使用时,我很少推荐图书馆。但考虑到迄今为止的大量答案,似乎值得指出的是,流行的图书馆“date-fns”有一个函数isValid。以下留档取自他们的网站:

isValid参数v2.0.0之前v2.0.0起
新日期()真正真正
新日期('2016-01-01')真正真正
新日期(")虚假虚假
新日期(1488370835081)真正真正
新日期(NaN)虚假虚假
'2016-01-01'错误码虚假
''错误码虚假
1488370835081错误码真正
NaN错误码虚假

在阅读了到目前为止的每个答案之后,我将提供最简单的答案。

这里的每个解决方案都提到调用date.getTime()。但是,这是不需要的,因为从Date到Number的默认转换是使用getTime()值。是的,你的类型检查会抱怨的。:)OP cleary知道他们有一个Date对象,所以也不需要测试。

要测试无效日期:

isNaN(date)

要测试有效日期:

!isNaN(date)

或(感谢icc97提供此替代方案)

isFinite(date)

或打字稿(感谢pat-migliacio)

isFinite(+date)

日期FNS有一个名为isExists的函数。它检查日期是否存在(2月31日不应该存在)。

示例:

// For the valid date:const result = isExists(2018, 0, 31)//=> true
// For the invalid date:const result = isExists(2018, 1, 31)//=> false

文档:https://date-fns.org/v2.28.0/docs/isExists

这里只有少数人(@Zen,@Dex,@wanglab…)在2月,4月,6月等月份中使用javascript容忍度溢出天数。

如果您指定要处理的格式(即yyyy-MM-dd),则您不必使用是解决方案中的javascript对象日期在所有

function leapYear(year) {return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);}
function validateDateStr(dateStr) {
if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/.test(dateStr) === false) {return false;}
var m = parseInt(dateStr.substr(5, 2));var d = parseInt(dateStr.substr(8, 2));var y = parseInt(dateStr.substr(0, 4));
// you can add a year check for a value greater than let's say 5000 :-D
if (m > 12 || d > 31) {return false;} else if (m == 2 && d > 28) {if (d == 29) {if (!leapYear(y)) {return false;}} else {return false;}} else if (d > 30 && (m == 4 || m == 6 || m == 9 || m == 11)) {return false;}
return true;}
console.log("2020-02-29:" + validateDateStr("2020-02-29")); // trueconsole.log("2020-02-30:" + validateDateStr("2020-02-30")); // falseconsole.log("2022-02-29:" + validateDateStr("2022-02-29")); // falseconsole.log("2021-02-28:" + validateDateStr("2021-02-28")); // trueconsole.log("2020-03-31:" + validateDateStr("2020-03-31")); // trueconsole.log("2020-04-30:" + validateDateStr("2020-04-30")); // trueconsole.log("2020-04-31:" + validateDateStr("2020-04-31")); // falseconsole.log("2020-07-31:" + validateDateStr("2020-07-31")); // trueconsole.log("2020-07-32:" + validateDateStr("2020-07-32")); // falseconsole.log("2020-08-31:" + validateDateStr("2020-08-31")); // trueconsole.log("2020-12-03:" + validateDateStr("2020-12-03")); // trueconsole.log("2020-13-03:" + validateDateStr("2020-13-03")); // falseconsole.log("0020-12-03:" + validateDateStr("0020-12-03")); // true//invalid regexconsole.log("20-12-03:" + validateDateStr("20-12-03")); // falseconsole.log("2020-012-03:" + validateDateStr("2020-012-03")); // falseconsole.log("2020-12-003:" + validateDateStr("2020-12-003")); // false