39

Possible Duplicate:
Detecting an “invalid date” Date instance in JavaScript

I was using the following to detect a valid date:

var text = $('#Date').val();
var date = Date.parse(text);

if (isNaN(date)) {
      // Invalid date
}

But found that Date.parse thinks the following are valid dates (mm/dd/yyyy)

  • 2/30/2011
  • 11/31/2011

Any other way to detect invalid dates when the number of days surpasses the total number of days in the month?

UPDATE: An even larger problem is that the jQuery validation plugin doesn't detect this as an invalid date either!

SOLUTION:

Based on @Guffa's comments I have created the following function to validate dates:

function validDate(text) {

    var date = Date.parse(text);

    if (isNaN(date)) {
        return false;
    }

    var comp = text.split('/');

    if (comp.length !== 3) {
        return false;
    }

    var m = parseInt(comp[0], 10);
    var d = parseInt(comp[1], 10);
    var y = parseInt(comp[2], 10);
    var date = new Date(y, m - 1, d);
    return (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d);
}
5
  • 3
    Date.parse thinks not that they are correct, but it converts them into correct dates for you. E.g. 2/30/2011 will end as 03/02/2011 Commented Nov 11, 2011 at 18:21
  • 1
    after voting to close as dupe, i realized that the provided question is not identical, although it's related. Commented Nov 11, 2011 at 18:22
  • 1
    Since I needed to support input in multiple locales, we implemented our own date parser. The only way we found to detect this error was to compare the month string that we parsed with the month that comes out of the generated Date Commented Nov 11, 2011 at 18:33
  • Simply use moment.js like that momentjs.com/docs/#/parsing/is-valid <3 Commented Oct 14, 2013 at 19:57
  • Possible duplicate of Detecting an "invalid date" Date instance in JavaScript Commented Jul 14, 2018 at 11:47

5 Answers 5

76

To check if a date is valid you can parse the components of the date, create a Date object from it, and check if the components in the data is the same as the parsed components. If you create a Date object from compnents that are out of range, the values will flow over to the next/previous period to create a valid date.

For example, new Date(2011,0,42) will create an object that contains the date 2/11/2011 instead of 1/42/2011.

By parsing the components instead of the full date you will also get around the problem with different date formats. My browser will for example expect a date format like y-m-d rather than d/m/y.

Example:

var text = '2/30/2011';
var comp = text.split('/');
var m = parseInt(comp[0], 10);
var d = parseInt(comp[1], 10);
var y = parseInt(comp[2], 10);
var date = new Date(y,m-1,d);
if (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d) {
  alert('Valid date');
} else {
  alert('Invalid date');
}

Demo: http://jsfiddle.net/Guffa/UeQAK/

Sign up to request clarification or add additional context in comments.

3 Comments

Maybe I'm paranoid, but I wonder if it would be safer to use new Date(Date.UTC()) and Date.prototype.getUTC*() instead.
Just what I need...Does this consider leap year?
What is the purpose of -1 on the month, only to add it back later?
3

If your date format is fixed as M/D/YYYY, you could re-format the parsed date and see if it matches the input:

var d = new Date(Date.parse(str))
return str === (d.getMonth()+1)+'/'+d.getDate()+'/'+d.getYear();

However, that won't tolerate whitespace or zero-padded numbers.

If you don't need to keep the user's input exactly, you could just reformat the date anyway and pretend that was what they typed.

But if you can't do that either, I'd parse out the components myself using a RegExp and then compare them to values from the Date methods.

Comments

0

You could write a script to do this manually:

function checkDate(day, month) {
   if ((month == 4 || month == 6 || month == 9 || month == 11) && day < 30) {
       alert("Date is valid")
   }
   else if (month == 2 && day <= 28) {
       alert("Date is valid")
   }
   else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day <= 31) {
       alert("Date is valid")
   }
   else {
       alert("Date is in-valid")
   }
}

Of course, you would also need something to look out for leap years, but just remember that any year divisible by 4 and not by 100 is a leap year unless the first two digits of the year are divisible by 4. That should be easy to include in this function.

1 Comment

in statement == not = ?
0

The example is wrong

the correct is

if ((month == 4 || month == 6 || month == 9 || month == 11) && day <= 30)

<= instead of =

But the example are great!

Comments

0

A simple, intrinsic way to achieve this can be:

let dateObj = document.getElementById('Date');
if (dateObj.validity.badInput) {
 // show error message
}

Now some date formatting can be done, but HTML date-picker event has properties like badInput and valid to check invalid dates.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.