Saturday, November 11, 2006

Creating an IsDate() Function in JavaScript

One of those things that always seems to be missing from the Date object in Javascript is the ability to determine if a string contains a valid date expression. I find that sorely lacking myself. Coupled with the fact that I needed it badly for a major project I'm working on, this became a really pressing concern of mine. Hence, a new blog entry.

A quick search on Google turned up a few different ideas. But my favorite one was this, which I found on http://www.thescripts.com/:


There are a lot of good answers on this thread but personally I think
javascript itself is a better date validator.

function isDate(sDate) {
var scratch = new Date(sDate);
if (scratch.toString() == "NaN" scratch.toString() == "Invalid Date") {
alert("Not a Date");
return false;
} else {
return true;


}
}

Javascript's date parser is actually very robust and powerful and able
to hande 1/20/2004 as well as January 20 2004. IE returns NaN (not a
number) when it can't figure out a date, Mozilla (gekko engine) returns
Invalid Date.

I like this one because it's simple, short, and to-the-point. It's unfortunate that the poster was anonymous, because I'd like to give him/her credit for it. At the least, I can provide a link back to the thread. It's response number ten in the thread, from user pcx99..

10 comments:

Anonymous said...

Hi... I'm tes your funtion but the result not is correct

sorry

fecha = "02/29/2007"
alert(isDate(fecha));
//the result si true

Anonymous said...

I assume the original code would be the following without errors:

function isDate(sDate) {
var scratch = new Date(sDate);
if (scratch.toString() == "NaN" || scratch.toString() == "Invalid Date") {
alert("Not a Date");
return false;
} else {
return true;
}

Anonymous said...

function btn_TestOnClick(){
//This function not is correct to all dates
//the 29 of Febrary no exist in the calendar...

var fecha = "";
fecha = "02/29/2007"; //this date is invalid
alert(isDate(fecha)); //the result is true
}


function isDate(sDate) {
var scratch = new Date(sDate);
if (scratch.toString() == "NaN" || scratch.toString() == "Invalid Date") {
alert("Not a Date");
return false;
}else{
return true;
}
}

Anonymous said...

function isDate(str){
if (typeof str !== "string") {
alert('Invalid date: ' + str);
return false;
}

// format: dd.mm.yyyy or dd/mm/yyyy or dd-mm-yyyy ... for Turkish
var s = String(str).split(/[-\/., ]/);

var dd = parseInt(s[0]);
var mm = parseInt(s[1]);
var yyyy = parseInt(s[2]);

var dateStr = mm + '/' + dd + '/' + yyyy;

// mm-dd-yyyy yyyy/mm/dd mm/dd/yyyy mmm dd, yyyy mm dd, yyyy ... for Date().parse(..)
var dt = new Date(dateStr);

if (dt.getDate() == dd && dt.getMonth() + 1 == mm && dt.getFullYear() == yyyy) {
alert('Valid date: ' + dt.toLocaleString());
return true;
}
else{
alert('Invalid date: ' + dt.toLocaleString());
return false;
}
}

Anonymous said...

I tried this function and tested entering the date 11/31/2009 and instead of coming back and saying it was invalid, it assumed that you meant 12/1/2009 - ?????

Profesor said...

02/29/2007 in terms of coding is a valid date, it resolves to the 01/03/2007 so java wont complain about the validity

Bitco Software said...

I see that others have commented on your orig code. You ommited the || or in the if statement. I didn't find this out until I cut and pasted and tried to run it. If you can, would be great if you edited the orig post so others don't run into that.

Thanks,
Cory

Anonymous said...

There's a date that is valid as far as JS is concerned and then there is a date that really exists in the calendar. That's why the posted function considers 02/29/2007 to be valid... it is, it's the first of March 2007 in JavaScript-world.

Here's a short and (I think) elegant method of testing that a date is valid in the real world...

function isValidDate(i) { // i = date in string format default YYYYMMDD
// Known assumptions:
// Any supplied format string contains one block of each of Y, M and D
// Month block is numeric (not a month name)
var fm = (arguments.length>1)?arguments[1].toUpperCase():'YYYYMMDD',
dt = new Date(y=i.substr(n=fm.indexOf('Y'),fm.lastIndexOf('Y')-n+1),
m=i.substr(n=fm.indexOf('M'),fm.lastIndexOf('M')-n+1)-1,
d=i.substr(n=fm.indexOf('D'),fm.lastIndexOf('D')-n+1));
return dt.getDate()==d && dt.getMonth()==m && dt.getFullYear().toString().substr(-y.length,y.length)==y;
};

Usage:

alert(isValidDate('20000229') + ' ' +
isValidDate('19000229') + '\n' +
isValidDate('2012-01-13','YYYY-MM-DD') + ' ' +
isValidDate('10-15-1840','MM-DD-YYYY'));


Alternatively, you could extend the String object like this...


String.prototype.isValidDate = function () { // date in string format default YYYYMMDD
// Known assumptions:
// Any supplied format string contains one block of each of Y, M and D
// Month block is numeric (not a month name)
var fm = (arguments.length>0)?arguments[0].toUpperCase():'YYYYMMDD',
dt = new Date(y=this.substr(n=fm.indexOf('Y'),fm.lastIndexOf('Y')-n+1),
m=this.substr(n=fm.indexOf('M'),fm.lastIndexOf('M')-n+1)-1,
d=this.substr(n=fm.indexOf('D'),fm.lastIndexOf('D')-n+1));
return dt.getDate()==d && dt.getMonth()==m && dt.getFullYear().toString().substr(-y.length,y.length)==y;
};

Usage:

alert('20000229'.isValidDate() + ' ' +
'19000229'.isValidDate() + '\n' +
'2012-01-13'.isValidDate('YYYY-MM-DD') + ' ' +
'10-15-1840'.isValidDate('MM-DD-YYYY'));

Anthony Garrett (author of SCW and JACS date pickers).

Anonymous said...

OK, so a little debugging and tweaking to make it work in IE8...

// A function that checks that a date string is a real date

function isRealDate(i) { // i = date in string format default YYYYMMDD
// Known assumption: Any supplied format string contains one block of each of Y, M and D
// Valid options: YY (abbreviated year number), YYYY (full year number), MM (month number), DD (Day number)
var fm = (arguments.length>1)?arguments[1].toUpperCase():'YYYYMMDD', y, m, d,
dt = new Date(y=i.substring(fm.indexOf('Y'),fm.lastIndexOf('Y')+1),
m=i.substring(fm.indexOf('M'),fm.lastIndexOf('M')+1)-1,
d=i.substring(fm.indexOf('D'),fm.lastIndexOf('D')+1));
return dt.getDate()==d && dt.getMonth()==m && dt.getFullYear().toString().slice(-y.length)==y;
};

// Alternatively, extend the String object...

String.prototype.isRealDate = function () { // default format YYYYMMDD
// Known assumptions: Any supplied format string contains one block of each of Y, M and D
// Valid options: YY (abbreviated year number), YYYY (full year number), MM (month number), DD (Day number)
var fm = (arguments.length>0)?arguments[0].toUpperCase():'YYYYMMDD', y, m, d,
dt = new Date(y=this.substring(fm.indexOf('Y'),fm.lastIndexOf('Y')+1),
m=this.substring(fm.indexOf('M'),fm.lastIndexOf('M')+1)-1,
d=this.substring(fm.indexOf('D'),fm.lastIndexOf('D')+1));
return dt.getDate()==d && dt.getMonth()==m && dt.getFullYear().toString().slice(-y.length)==y;
};

joemill00077711 said...

The next time I read a weblog, I hope that it doesnt disappoint me as a lot as this one. I mean, I do know it was my option to read, but I actually thought youd have one thing attention-grabbing to say. All I hear is a bunch of whining about one thing that you can repair in the event you werent too busy in search of attention. casino bonus