Detecting an "invalid date" Date instance in JavaScript

Asked 2023-09-20 20:57:55 View 284,513

I'd like to tell the difference between valid and invalid date objects in JS, but couldn't figure out how:

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'

Any ideas for writing an isValidDate function?

  • Ash recommended Date.parse for parsing date strings, which gives an authoritative way to check if the date string is valid.
  • What I would prefer, if possible, is have my API accept a Date instance and to be able to check/assert whether it's valid or not. Borgar's solution does that, but I need to test it across browsers. I also wonder whether there's a more elegant way.
  • Ash made me consider not having my API accept Date instances at all, this would be easiest to validate.
  • Borgar suggested testing for a Date instance, and then testing for the Date's time value. If the date is invalid, the time value is NaN. I checked with ECMA-262 and this behavior is in the standard, which is exactly what I'm looking for.
  • I deleted my original answer since checking if NaN is a much better solution than comparing to a string "Invalid Date". I'll have to make use of the isNaN solution, myself. - anyone
  • @orip, "have my API accept a Date instance and to be able to check/assert whether it's valid or not" Have you tried: isNan(d.getTime())==true on the date instance? - anyone
  • You could remove the if statement by changing the body of the function to: return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) ); - anyone
  • @styfle - sure, but why? - anyone
  • @styfle - guess it's a style preference: I find it clearer to separate the type check from the equality logic. - anyone

Answers

Here's how I would do it:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (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
}

Update [2018-05-31]: If you are not concerned with Date objects from other JS contexts (external windows, frames, or iframes), this simpler form may be preferred:

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

Update [2021-02-01]: Please note that there is a fundamental difference between "invalid dates" (2013-13-32) and "invalid date objects" (new Date('foo')). This answer does not deal with validating date input, only if a Date instance is valid.

Answered   2023-09-20 20:57:55

  • instanceof breaks across frames. Duck-typing can work just fine too: validDate == d && d.getTime && !isNaN(d.getTime()); -- Since the question is for a general utility function I prefer to be more strict. - anyone
  • @Borgar, just found my answer: "The problems arise when it comes to scripting in multi-frame DOM environments. In a nutshell, Array objects created within one iframe do not share [[Prototype]]’s with arrays created within another iframe. Their constructors are different objects and so both instanceof and constructor checks fail." - anyone
  • you don't even need d.getTime just isNan(d) - anyone
  • Could be simplified like this: d instanceof Date && !isNaN(d.getTime()) - anyone
  • Thanks for the answer, but I wish to stress @Borgar and @blueprintChris comments: if I parse the digit 1 for example I would still have a valid date resulting to Mon Jan 01 2001 00:00:00 which is indeed a date, however for the purpose of my application it is completely useless. Thus, there is some more input validation needed in my case at least. This answer validates a dateObject not a Date! - anyone

Instead of using new Date() you should use:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse() returns a timestamp, an integer representing the number of milliseconds since 01/Jan/1970. It will return NaN if it cannot parse the supplied date string.

Answered   2023-09-20 20:57:55

  • -1 Dunno why this has so many up votes, Date.parse is implementation dependent and definitely not to be trusted to parse general date strings. There is no single format that is parsed correctly in popular browsers, much less all those in use (though eventually the ISO8601 format specified in ES5 should be ok). - anyone
  • If you use the new Date('foo') that's basically equivalent with the Date.parse('foo') method. See: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… So what @RobG said, it also applies to it. - anyone
  • This test would fail in Chrome. For example, Date.parse('AAA-0001') in Chrome gives me a number. - anyone
  • failed ... detect all numeric values - anyone
  • Needs the American MM/DD/YYYY format to work. Date.parse('24/12/2021') returns NaN. - anyone

You can check the validity of a Date object d via

d instanceof Date && isFinite(d)

To avoid cross-frame issues, one could replace the instanceof check with

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

A call to getTime() as in Borgar's answer is unnecessary as isNaN() and isFinite() both implicitly convert to number.

Answered   2023-09-20 20:57:55

  • Try this in chrome - Object.prototype.toString.call(new Date("2013-07-09T19:07:9Z")). It will return "[object Date]". According to you, therefore, "2013-07-09T19:07:9Z", should be a valid date. But it is not. You can verify it, again in chrome, by doing var dateStr = new Date("2013-07-09T19:07:9Z"); dateStr It will return invalid date. - anyone
  • @Tintin: that's what isFinite() is for - toString.call() is only a replacement for the instanceof part of the check - anyone
  • Will comparing with '[object Date]' work with non-english browsers? I doubt it. - anyone
  • @kristianp actually it probably will and is probably even part of the ECMAScript spec. But, yes, it seems ugly. - anyone
  • To me the first approach here is the very best option, although I'm not sure if there's any real-world advantage of using isFinite over isNaN (both work just fine with Date(Infinity)). Furthermore, if you want the opposite condition, it gets a bit simpler: if (!(date instanceof Date) || isNaN(date)). - anyone

shortest answer to check valid date

if(!isNaN(date.getTime()))

Answered   2023-09-20 20:57:55

  • The only problem is if date is not of type Date; you get a JS error. - anyone
  • @Andrew you need to create the date Object and if you already have an object then use date && !isNaN(date.getTime()) - anyone
  • Right, like the other answers from 8 years ago. :P stackoverflow.com/a/1353945/2321042 - anyone
  • doesn't work as intended, i can enter date as 60/80/9000 and it returns Thu Oct 30 9006 00:00:00 GMT+0000 (Greenwich Mean Time) as the date? - anyone
  • As long as they're using var date = new Date(str), then this answer would be the shortest and most appropriate. - anyone

My solution is for simply checking whether you get a valid date object:

Implementation

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

Usage

var d = new Date("lol");

console.log(d.isValid()); // false

d = new Date("2012/09/11");

console.log(d.isValid()); // true

Answered   2023-09-20 20:57:55

I have seen some answers that came real close to this little snippet.

JavaScript way:

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

ES2015 way:

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

Answered   2023-09-20 20:57:55

  • Not sure if I'm missing something but Isn't doing new Date() twice pointless? - anyone
  • The latter has nothing to do with TypeScript. It is perfectly valid JS. - anyone
  • Passing any value that the Date constructor can convert to a valid Date object is treated as a valid date, e.g. isValidDate(0) and isValidDate(['0']) return true. - anyone
  • @RobG you are correct about isValidDate(0) but isValidDate(['0']) comes back false. zero is convertable to new Date(0) and is valid. - anyone
  • 0 is neither a valid Date object nor is it a valid date. As a timestamp it requires additional information to convert to a date (e.g. epoch and value). Running isValidDate(['0']) in your answer returns true. - anyone

You can simply use moment.js

Here is an example:

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

The validation section in the documentation is quite clear.

And also, the following parsing flags result in an invalid date:

  • overflow: An overflow of a date field, such as a 13th month, a 32nd day of the month (or a 29th of February on non-leap years), a 367th day of the year, etc. overflow contains the index of the invalid unit to match #invalidAt (see below); -1 means no overflow.
  • invalidMonth: An invalid month name, such as moment('Marbruary', 'MMMM');. Contains the invalid month string itself, or else null.
  • empty: An input string that contains nothing parsable, such as moment('this is nonsense');. Boolean.
  • Etc.

Source: http://momentjs.com/docs/

Answered   2023-09-20 20:57:55

  • Best solution, extremely easy to implement , works with any formatting (my case is dd/MM/yyyy), also knows the leap years and doesn't convert invalid dates (i.e. 29/02/2015) into valid ones by itself (i.e. 30/03/2015). To check a date in the formad dd/MM/yyyy I've just had to use moment("11/06/1986", "DD/MM/YYYY").isValid(); - anyone
  • This use of Moment has been deprecated :( - anyone
  • Bummer. moment.js still didn't solve my Chrome-specific problem where it guesses ok dates out of phrases. m = moment("bob 2015"); m.isValid(); // true - anyone
  • This use has not been depreciated. Calling moment(input) without a format string is depreciated (unless the input is ISO formatted). - anyone
  • Usage of moment.js may be simple, but is an enormous overhead. This library is HUGE. I downvoted your answer. - anyone

After reading every answer so far, I am going to offer the most simple of answers.

Every solution here mentions calling date.getTime(). However, this is not needed, as the default conversion from Date to Number is to use the getTime() value. Yep, your type checking will complain. :) And the OP cleary knows they have a Date object, so no need to test for that either.

To test for an invalid date:

isNaN(date)

To test for a valid date:

!isNaN(date)

or (thanks to icc97 for this alternative)

isFinite(date) 

or typescript (thanks to pat-migliaccio)

isFinite(+date) 

Answered   2023-09-20 20:57:55

  • You can also reverse the logic and use isFinite(date) - to test for a valid date. - anyone
  • @icc97 I added your suggestion to solution. - anyone
  • For TypeScript, to avoid type errors you can coerce the date into a number using isNaN(+date). - anyone
  • @PatMigliaccio nice, added to solution. 👍 - anyone
  • @PatMigliaccio I do not like implcit type casting so in my codebase it would have to be: isFinite(Number(date)). - anyone

Would like to mention that the jQuery UI DatePicker widget has a very good date validator utility method that checks for format and validity (e.g., no 01/33/2013 dates allowed).

Even if you don't want to use the datepicker widget on your page as a UI element, you can always add its .js library to your page and then call the validator method, passing the value you want to validate into it. To make life even easier, it takes a string as input, not a JavaScript Date object.

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

It's not listed as a method, but it is there-- as a utility function. Search the page for "parsedate" and you'll find:

$.datepicker.parseDate( format, value, settings ) - Extract a date from a string value with a specified format.

Example usage:

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

(More info re specifying date formats is found at http://api.jqueryui.com/datepicker/#utility-parseDate)

In the above example, you wouldn't see the alert message since '01/03/2012' is a calendar-valid date in the specified format. However if you made 'stringval' equal to '13/04/2013', for example, you would get the alert message, since the value '13/04/2013' is not calendar-valid.

If a passed-in string value is successfully parsed, the value of 'testdate' would be a Javascript Date object representing the passed-in string value. If not, it'd be undefined.

Answered   2023-09-20 20:57:55

  • Upvote for being the first answer working with non english / locale date formats. - anyone
  • The previous comment is incorrect and misleading. The Date object in javascript handles date in any locale and a lot of ISO formats (and even some non ISO depending on implementation) - anyone
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());

Answered   2023-09-20 20:57:55

  • It's the same @Borgar wrote 2 years ago... What's new?? - anyone
  • It's two lines instead of ugly nested if statements. - anyone
  • Warning: null values passes as valid - anyone
  • That doesn't check if the date is valid, it just tests if the built–in parser is able to parse it to a valid Date using whatever implementation specific heuristics it likes. There are many examples where Date.parse(string) returns a valid Date object in one implementation and an invalid Date, or different valid Date, in another. - anyone
  • This is useful when you know the year, month, and day and check if that specific date exists on a calendar. - anyone

I really liked Christoph's approach (but didn't have enough of a reputation to vote it up). For my use, I know I will always have a Date object so I just extended date with a valid() method.

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

Now I can just write this and it's much more descriptive than just checking isFinite in code...

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

Answered   2023-09-20 20:57:55

  • Extending the prototype? That's a big JavaScript no no! - anyone
  • Upvoting because of the isFinite worked for me perfectly. But yes, pointless to extend the prototype. !isFinite on a Date will catch the fact that the Date is Invalid Date. Also worth noting my context is inside Node. - anyone
  • I have not idea why some suggest isFinite over isNaN, since isFinite returns true for a greater range of numbers (-∞ < d < +∞) than a Date object can handle (-8.64e15 < d < +8.64e15) and a Date object with a time value of NaN is explicitly intended to represent an invalid Date. !isNaN(date) is more semantic, more accurate and less to type. - anyone

I use the following code to validate values for year, month and 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;
}

For details, refer to Check date in javascript

Answered   2023-09-20 20:57:55

  • str isn't being used. - anyone
  • ok, now this is genius and as far as I can see the best and only way to validate a crappy date like "Feb 31st 1970". Wish I could give 10 upvotes. - anyone
  • Link is now broken - anyone
  • This answer actually validates the date value, not just the date format. Only thing I would add is check the value you are passing in for month because in Javascript months are 0-based. You must subtract 1 from the passed-in value to get the correct JS month value. (month = month - 1; before var d = new Date(...) For example, if you pass in "2" to the month parameter in Date(), it will create March. - anyone
  • Months in Date objects are zero based. So new Date(year, month -1, day); - anyone

you can check the valid format of txDate.value with this scirpt. if it was in incorrect format the Date obejct not instanced and return null to dt .

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

And as @MiF's suggested in short way

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

Answered   2023-09-20 20:57:55

  • there is a problem - !isNan(new Date(123)) this is also return true - anyone
  • @AbhishekTomar use the first one. does it return true? - anyone
  • both are the same just the writing style is different. - anyone

Too many complicated answers here already, but a simple line is sufficient (ES5):

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

or even in ES6 :

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

Answered   2023-09-20 20:57:55

  • From MDN: "The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC or NaN..." So running a potential date through this function returns either an integer or NaN. Then the isNaN() function will give a clean boolean telling you whether the original value was a valid date object or not. This is enough to make a spot check, but the example above then attaches this method to the Date object to make the functionality easily available and readable throughout your program. - anyone
  • if d is boolean you will receive 0 or 1 that not is a Nan !! - anyone
  • @davcup just tested using Date.parse(true), I correctly get a NaN. - anyone
  • says 02/30/2001 is a valid date :( - anyone

Why am I writing a 48th answer after so many have tried before me? Most of the answers are partly correct and will not work in every situation, while others are unnecessarily verbose and complex. Below is a very concise solution. This will checking if it is Date type and then check if a valid date object:

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

Now for parsing date Text: Most of the solutions use Date.parse(), or "new Date()" -- both of these will fail certain situations and can be dangerous. JavaScript parses a wide variety of formats and also is dependent on localization. For example, strings like "1" and "blah-123" will parse as a valid date.

Then there are posts that either use a ton of code, or a mile-long RegEx, or use third party frameworks.

This is dead simple method to validate a date string.

function isDate(txt) {
   var matches = txt.match(/^\d?\d\/(\d?\d)\/\d{4}$/); //Note: "Day" in the RegEx is parenthesized
   return !!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>

The first line of isDate parses the input text with a simple RegEx to validate for date formats mm/dd/yyyy, or m/d/yyyy. For other formats, you will need to change the RegEx accordingly, e.g. for dd-mm-yyyy the RegEx becomes /^(\d?\d)-\d?\d-\d{4}$/

If parse fails, "matches" is null, otherwise it stores the day-of-month. The second lines does more tests to ensure it is valid date and eliminates cases like 9/31/2021 (which JavaScript permits). Finally note the double-whack (!!) converts "falsy" to a boolean false.

Answered   2023-09-20 20:57:55

  • This says 9/31/2021 and 2/29/2021 are valid dates, but they aren't. - anyone
  • Good point Rokit! Javascript Date is permissive and allows higher (or lower) numbers and treats higher month-days into the following month(s). So "2/29/2021" is computed as Mar 01 2021. I updated the function to eliminate this issue, and it now checks min/max range including leap year. - anyone
  • Okay, but this only works if the date is in format mm/dd/yyyy. If it's in format yyyy/dd/mm or yyyy/mm/dd then this will return false. - anyone
  • @EliezerBerlin, I already mentioned that. You just need to change RegEx accordingly for other date formats. For yyyy/dd/mm, the RegEx is /^\d{4}/(\d\d)/\d\d$/ For yyyy/mm/dd, it is /^\d{4}/\d\d/(\d\d)$/ Let me know if that helped. This works for any format but note the "\d\d" part of the RegEx corresponding to "day" portion should be parenthesized - anyone
  • @VijayJagdale Thanks! I was concerned that you're hardcoding the format. Though it probably doesn't matter, because you can simply put a hint or tooltip underneath the field saying "The date should be in format MM/DD/YYYY" and users will figure it out. - anyone

This just worked for me

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

However this didn't work

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

Answered   2023-09-20 20:57:55

  • I believe this is browser dependent. - anyone
  • @barrypicker What do you mean this is browser dependent? - anyone
  • You can do: `${new Date('foo')}` === 'Invalid Date' - anyone
  • Use the .toString() method if you're going to do type comparison. new Date('foo').toString() === 'Invalid Date' will return true - anyone
  • @AjilO.—it means different implementations may parse the input string (in this case, 'foo') differently so what one browser says is valid another might say is a different date or invalid. - anyone

None of these answers worked for me (tested in Safari 6.0) when trying to validate a date such as 2/31/2012, however, they work fine when trying any date greater than 31.

So I had to brute force a little. Assuming the date is in the format mm/dd/yyyy. I am using @broox answer:

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"); // false
validStringDate("2/30/2012"); // false

Answered   2023-09-20 20:57:55

For Angular.js projects you can use:

angular.isDate(myDate);

Answered   2023-09-20 20:57:55

  • This returns true for when testing a date object that has been initialized with an Invalid Date. - anyone

I wrote the following solution based on Borgar's solution. Included in my library of auxiliary functions, now it looks like this:

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

Answered   2023-09-20 20:57:55

I rarely recommend libraries when one can do without. But considering the plethora of answers so far it seems worth pointing out that the popular library "date-fns" has a function isValid. The following documentation is taken from their website:

isValid argument Before v2.0.0 v2.0.0 onward
new Date() true true
new Date('2016-01-01') true true
new Date('') false false
new Date(1488370835081) true true
new Date(NaN) false false
'2016-01-01' TypeError false
'' TypeError false
1488370835081 TypeError true
NaN TypeError false

Answered   2023-09-20 20:57:55

Date.prototype.toISOString throws RangeError (at least in Chromium and Firefox) on invalid dates. You can use it as a means of validation and may not need isValidDate as such (EAFP). Otherwise it's:

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

Answered   2023-09-20 20:57:55

  • It seems it is the only function that throws an error by ECMA-262 definition. 15.9.5.43 Date.prototype.toISOString ( ) This function returns a String value represent the instance in time represented by this Date object. The format of the String is the Date Time string format defined in 15.9.1.15. All fields are present in the String. The time zone is always UTC, denoted by the suffix Z. If the time value of this object is not a finite Number a RangeError exception is thrown. - anyone
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;
}

Answered   2023-09-20 20:57:55

I've written this function. Pass it a string parameter and it will determine whether it's a valid date or not based on this format "dd/MM/yyyy".

here is a test

input: "hahaha",output: false.

input: "29/2/2000",output: true.

input: "29/2/2001",output: 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;
    }
}

Answered   2023-09-20 20:57:55

None of the above solutions worked for me what did work however is

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

the code above will see when JS makes 02/31/2012 into 03/02/2012 that it's not valid

Answered   2023-09-20 20:57:55

  • Ok, but this tests if a string is a date in a M/D/Y format, not "the difference between valid and invalid date objects". It's not really what this is question about. - anyone
  • the reason why its checked against the format is to check if the date has changed after it was parsed - anyone
  • Isn't the OP asking for a method to return a Boolean, not a formatted string? - anyone
  • The sample code does return a boolean, the formating plays a part in testing for some of the invalid cases. - anyone

Date object to string is more simple and reliable way to detect if both fields are valid date. e.g. If you enter this "-------" to the date input field. Some of the above answers won't work.

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

Answered   2023-09-20 20:57:55

you can convert your date and time to milliseconds getTime()

this getTime() Method return Not a Number NaN when not valid

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

Answered   2023-09-20 20:57:55

  • This doesn't work !isNaN(new Date("2/30/2012").getTime()) returns true - anyone

I combined the best performance results I found around that check if a given object:

The result is the following:

function isValidDate(input) {
  if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
    return false;

  var time = input.getTime();
  return time === time;
};

Answered   2023-09-20 20:57:55

A ready function based on top rated answer:

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

Answered   2023-09-20 20:57:55

Simple and elegant solution:

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

sources:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] Incorrect date shown in new Date() in JavaScript

Answered   2023-09-20 20:57:55

  • date.getDate() == day is insufficient to determine if the date is valid. The original date format will return an invalid date in some implementations regardless of whether the date is valid or not. Also "1970-01-01 00:00" if parsed correctly will return false (i.e. Boolean(+new Date("1970-01-01")) returns false). - anyone
  • It will work in Safari if you use the format const date = new Date(year, month, day); Note that month is 0 indexed this way so you may have to subtract one to line it up correctly. - anyone

No one has mentioned it yet, so Symbols would also be a way to go:

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

Be aware of: https://caniuse.com/#search=Symbol

Answered   2023-09-20 20:57:55