Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 2/8888/2016 a valid date in IE and Firefox?

If you take the following:

var s = "2/8888/2016";
var d = new Date(s);
alert(d);

In Chrome, you'll get:

Invalid Date

But in IE and Firefox, you'll get:

Fri Jun 01 2040 00:00:00 GMT-0500 (Central Daylight Time)

It appears to be just adding 8888 days to Feb 01. Instead, I would expect the date to be considered invalid. Is there a way I can make FireFox and IE think this date string is invalid?

like image 499
lhan Avatar asked Jan 13 '16 22:01

lhan


2 Answers

Short answer:

It's a misbehaviuor of the browsers you're mentioning.

You have to check date is in correct format on your own. But it's quite trivial, I suggest this approach:

Split the date in year y, month m, day d and create the Date object:

var date = new Date( y, m - 1, d ); // note that month is 0 based

Then compare the original values with the logical values obtained using the Date methods:

var isValid = date.getDate() == d &&
              date.getMonth() == m-1 &&
              date.getFullYear() == y;

Before doing all of this you may want to check if the date string is valid for any browser:

Detecting an "invalid date" Date instance in JavaScript



Long answer:

Firefox (and IE) accepting "2/8888/2016" as a correct string sate format seem to be a bug / misbehaviour.

In fact according to ECMAScript 2015 Language Specification when Date() is invoked with a single string argument should behave just as Date.parse()

http://www.ecma-international.org/ecma-262/6.0/#sec-date-value

The latter

attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.1.16)

..that is specified here

http://www.ecma-international.org/ecma-262/6.0/#sec-date-time-string-format

where you can read

The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ

[...]

MM is the month of the year from 01 (January) to 12 (December).

DD is the day of the month from 01 to 31.


It seems that Firefox is interpreting the string value as when Date() is invoked with multiple arguments.

From

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Note: Where Date is called as a constructor with more than one argument, if values are greater than their logical range (e.g. 13 is provided as the month value or 70 for the minute value), the adjacent value will be adjusted. E.g. new Date(2013, 13, 1) is equivalent to new Date(2014, 1, 1), both create a date for 2014-02-01 (note that the month is 0-based). Similarly for other values: new Date(2013, 2, 1, 0, 70) is equivalent to new Date(2013, 2, 1, 1, 10) which both create a date for 2013-03-01T01:10:00.

This may explain how "2/8888/2016" turns into 2040-05-31T22:00:00.000Z

like image 85
Paolo Avatar answered Sep 28 '22 17:09

Paolo


There's no way to make IE and FF think it's invalid, except:

  • you could change their javascript implementations
  • you use a library instead to deal with that.

We can also expect that Javascript, as a language, evolves and we can cross our fingers that browsers decide to follow a more strict specification. The problem of course is that every "fix" must be also backward compatible with previous versions of the language (does not happen always, Perl for example).

So the best thing by now is to use some library just like momentjs as suggested by Derek in the post comments.

like image 26
Leo Avatar answered Sep 28 '22 17:09

Leo