user1015214
user1015214

Reputation: 3081

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!

Upvotes: 27

Views: 28400

Answers (7)

Samyak jain
Samyak jain

Reputation: 137

I may be a little late for posting an answer but here is what worked best for me

var user_date = (`${user_values.month_value} ${user_values.date_value} , ${user_values.year_value}`)
        const d = new Date(user_date);
        let day = d.getDate()
        
        if(user_values.date_value != day){
            setdate_validation({
                display:'flex'
            })

          }
          else{
            setdate_validation({
                display:'none'
            })            
            console.log(user_values)

so in the above code what happens is i get different inputs from my user like one dropdown for date another for month and so on , i collect them and store it with .getdate() now .getdate() function returns the value of day , so if i stored (02 21 , 2002) then the .getdate() will return 21 ,

but there is a catch if i enter an invalid date like (02 30, 2002) where 30 is invalid in month of february then the .getdate() function returns not the same date but the date in next month or increment as much you are far away from a valid date like if 28 is valid and I entered 29 then .getdate() will show 1 as the output so i just compare the result of .getdate() with my current date value which is entered and if it is not same then the date is invalid.

(this code is from react using usestates)

Upvotes: 0

stemar
stemar

Reputation: 21

Assuming month input is 1-12 (1-based, not 0-based):

function isValidDate(year, month, day) {
    var d = new Date(year, month - 1, day);
    return month == d.getMonth() + 1;
}
isValidDate(2019, 12, 0); //=> false
isValidDate(2020, 2, 29); //=> true
isValidDate(2021, 2, 29); //=> false
isValidDate(2022, 2, 31); //=> false

Upvotes: 2

Kgopo
Kgopo

Reputation: 1

Basically an alternative to the above-mentioned examples

function (date) {

    if (!/(0[1-9]|1[0-9]|2[0-9]|3[0-1])\/(0[1-9]|1[0-2])\/([1-2][0-9]{3})/g.test(date))
    {
        alert('Incorrect date format please follow this form: dd/mm/yyyy');
        return;
    }
    else
    {
        // secondary validation
        const parts = (date).split('/').map((p) => parseInt(p, 10));
        let day = Number(parts[0]);
        let month = Number(parts[1]) - 1; // 0-indexed month
        let year = Number(parts[2]);
        let d = new Date(year, month, day);
        if (!(d.getFullYear() == year && d.getMonth() == month && d.getDate() == day))
        {
            alert('Incorrect date, please enter the correct day entry');
            return;
        }
    }
}

Upvotes: 0

Reuel Ribeiro
Reuel Ribeiro

Reputation: 1479

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

Upvotes: 4

Jeff Shaver
Jeff Shaver

Reputation: 3355

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.

Upvotes: 62

kennebec
kennebec

Reputation: 104810

The ususal way to validate a 'mm/dd/yyyy' date string is to create a date object and verify that its month and date are the same as the input.

function isvalid_mdy(s){
    var day, A= s.match(/[1-9][\d]*/g);
    try{
        A[0]-= 1;
        day= new Date(+A[2], A[0], +A[1]);
        if(day.getMonth()== A[0] && day.getDate()== A[1]) return day;
        throw new Error('Bad Date ');
    }
    catch(er){
        return er.message;
    }
}

isvalid_mdy('02/31/2000')

/* returned value: (Error)Bad Date */

Upvotes: 1

Stephen
Stephen

Reputation: 631

Are you able to use a library?

My first port of call for date handling in Javascript is moment.js: "A javascript date library for parsing, validating, manipulating, and formatting dates."

Upvotes: 4

Related Questions