Bradley Braithwaite
Bradley Braithwaite

Reputation: 1122

JavaScript Date Object in IE9 Allowing Invalid Date

When passing an invalid date via the constructor of a JavaScript Date() object IE9 appears to be constructing a valid Date e.g. "56 Aug 2009" returns a date object instance. Chrome by contrast, does not.

Having read the MSDN documentation regarding the Date object in IE9 (link below) and there is a paragraph that states:

JavaScript is fairly flexible about the date format. It allows for variants such as 8-24-2009, August 24, 2009, and 24 Aug 2009. For more information, see Formatting Date and Time Strings (JavaScript).

Above paragraph taken from: http://msdn.microsoft.com/en-us/library/ee532932(v=vs.94).aspx

The following snippet of code is used to check whether a date is valid. It works in Chrome but not in IE9:

function validateDate(d) {
    var dt = new Date(d);
    if (Object.prototype.toString.call(dt) !== "[object Date]") return false;

    return !isNaN(dt.getTime());
}

When running this code:

console.log(new Date("56 Aug 2009"));

IE9 Result

Fri Sep 25 00:00:00 UTC+0100 2009

Chrome Result

Invalid Date

Here is a JsFiddle with a more detailed example:

http://jsfiddle.net/WKMdc/8/

This behaviour is unexpected (perhaps due to incorrect assumptions or maybe a bug in the validate that's going unnoticed!).

What alternative method is there to verify a date is valid that would work in IE9 and allow the use of native browser features?

Upvotes: 2

Views: 4825

Answers (3)

Bradley Braithwaite
Bradley Braithwaite

Reputation: 1122

As also noted in the answer from João, the problem is that when creating a new Date object via the constructor the browser will "help" by performing an addition of days where there is a discrepancy e.g. 29-Feb-2013 is not a valid date (there are only 28 days in Feb in 2013) would become 01-Mar-2013, or + 1 days from the original date.

This is not terribly helpful as in my scenario I would want to flag the 29-Feb-2013 to the user as an invalid entry.

Trying to construct the below date:

var parsedDate = new Date("29 Feb 2013");

Returns the following Date object per browser:

IE9 - Fri Mar 1 00:00:00 UTC 2013

Safari - Fri Mar 01 2013 00:00:00 GMT+0000 (GMT)

Chrome - Fri Mar 01 2013 00:00:00 GMT+0000 (GMT Standard Time)

The same test with a "more incorrect" date:

var parsedDate = new Date("32 Aug 2013");

Returns the following Date object per browser:

IE9 - Tue Sep 1 00:00:00 UTC+0100 2012

Safari - Invalid Date

Chrome - Invalid Date

NB IE appears to be more lenient/flexible!

The proposed solution simply checks that the parsed month is the same as the expected month. If not, then one can conclude that a date addition has taken place and a validation message should be thrown:

function dateIsValid(dateString) {
            
     var month = dateString.split(" ")[1],
         year =  dateString.split(" ")[2];
            
     var parsedDate = new Date(dateString);
                    
     // create a date object with the day defaulted to 01
     var expectedMonth = new Date("01 " + month + " " + year);
            
     // if the month was changed by the Date constructor we can deduce that the date is invalid!
     if (parsedDate.getMonth() === expectedMonth.getMonth()) {
          return true;
     }
            
     return false;
}

Running the below produces consistant results across the browsers:

console.log(dateIsValid("01 Aug 2009")); // returns true
console.log(dateIsValid("56 Aug 2009")); // returns false
console.log(dateIsValid("29 Feb 2012")); // returns true
console.log(dateIsValid("29 Feb 2013")); // returns false

Disclaimer: This is of course, a workaround. But it's simple and works ok for my scenario!

Upvotes: 2

João Silva
João Silva

Reputation: 91349

That's a very interesting result. It seems that IE9 is parsing Aug 2009 as August 1, 2009, as expected, and then adds the first part of the string (56) to this date, i.e.:

August 1, 2009 + 56 days = September 25, 2009

It's like saying that the 32th day of January is February 1. It seems that this was a design decision; if you try to parse other date formats, you'll get the same behaviour:

console.log(new Date("08/32/2009")); // August 32, 2009
// LOG: Tue Sep 1 00:00:00 UTC+0100 2009

So, you can either validate your date with a custom regular expression, or live with this issue with IE9.

Upvotes: 1

Camrin Parnell
Camrin Parnell

Reputation: 449

You could use a regular expression to validate the format of the date and if it is a valid date then create a date object from it.

Upvotes: 1

Related Questions