Reputation: 3081
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
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
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
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
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
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
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