Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript date validation not validation February 31

I am trying to write some code with will validate form data. I have a date field which should have a mm/dd/yyyy format. I needed to catch exceptions such as February 31, so I added this code:

var d = new Date(dob);
if (isNaN(d.getTime())) { //this if is to take care of February 31, BUT IT DOESN'T!
  error = 1;
  message += "<li>Invalid Date</li>";
} else {
  var date_regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/;
  var validFormat = date_regex.test(dob);
  if (!(validFormat)) {
    error = 1;
    message += "<li>Invalid date format - date must have format mm/dd/yyyy</li>";
  }
}

However I found something very weird: while the date 02/32/2000 errors as an invalid date, 02/31/2000 does not!

like image 418
user1015214 Avatar asked Jan 17 '14 14:01

user1015214


People also ask

Why does JavaScript show invalid date?

The JavaScript exception "invalid date" occurs when a string leading to an invalid date has been provided to Date or Date. parse() .

How do you know if a date is valid?

Given date in format date, month and year in integer. The task is to find whether the date is possible on not. Valid date should range from 1/1/1800 – 31/12/9999 the dates beyond these are invalid. These dates would not only contains range of year but also all the constraints related to a calendar date.


2 Answers

Due to what I said in the comments...

Another way you could check if a date is valid is by checking whether or not the stuff you passed into the new Date function is the same as what comes out of it, like this:

// Remember that the month is 0-based so February is actually 1...
function isValidDate(year, month, day) {
    var d = new Date(year, month, day);
    if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) {
        return true;
    }
    return false;
}

then you could do this:

if (isValidDate(2013,1,31))

and it would return true if valid and false if invalid.

like image 82
Jeff Shaver Avatar answered Sep 18 '22 14:09

Jeff Shaver


After wrecking my head with the obscurity of Date .getMonth() (and also weekday by .getDay()) being 0-index (despite year, day and all the others not being like so... oh god...) I've re-wrote Jeff's answer to make it more readable and more friendly-usable to whom consume the method from outside.

ES6 code

You can call passing month as 1-indexed as you'd normally expect.

I've parsed inputs using Number constructor so I can use strict equality to more confidently compare values.

I'm using the UTC version methods to avoid having to deal with the local timezone.

Also, I broke steps down into some variables for the sake of readability.

/**
 *
 * @param { number | string } day
 * @param { number | string } month
 * @param { number| string } year
 * @returns { boolean }
 */
function validateDateString(day, month, year) {

    day = Number(day);
    month = Number(month) - 1; //bloody 0-indexed month
    year = Number(year);

    let d = new Date(year, month, day);

    let yearMatches = d.getUTCFullYear() === year;
    let monthMatches = d.getUTCMonth() === month;
    let dayMatches = d.getUTCDate() === day;

    return yearMatches && monthMatches && dayMatches;
}
like image 40
Reuel Ribeiro Avatar answered Sep 18 '22 14:09

Reuel Ribeiro