Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44735

Why does JavaScript interprete 1/1/0000 as 1/1/2000?

I encountered some strange behaviour, and while I don't really have an issue with it, I would like to know the reasoning behind it.

I wrote the following statements:

console.log(new Date("0000-1-1"));
console.log(new Date("0000-01-01"));
console.log(new Date("0000-01-01T00:00:00Z"));
console.log(new Date(0, 0, 1));

While all dates "appear" to be similar, and if you use normal days/months/years behave the same, it does not in this case.

The results are the following:

Sat Jan 01 2000 00:00:00 GMT+0100 (CET)
Sat Jan 01 0 01:00:00 GMT+0100 (CET)
Sat Jan 01 0 01:00:00 GMT+0100 (CET)
Mon Jan 01 1900 00:00:00 GMT+0100 (CET)

Which is quite interesting to me. I can agree with the last one, because the JavaScript spec clearly says the following:

year

Integer value representing the year. Values from 0 to 99 map to the years 1900 to 1999. See the example below.

I can also understand the second and third result, since this is depending on the RFC 2822. They do accept 4*DIGITS as a year, so 0000 should be the year 0 by the RFC spec (I didn't read it completely though).

It's only a bit weird that one of the Date constructors can be used for dates above 1900 while the other constructor allows dates from a wider range (RFC).

However, I do not understand the first result. Where does the year 2000 come from? I do understand that the date is not really an appropriate one, but shouldn't it return Invalid Date in stead of this date?

Upvotes: 5

Views: 2000

Answers (1)

James Donnelly
James Donnelly

Reputation: 128786

This is browser specific.

This is yet another area where JavaScript and browser inconsistency cause extra programmer pain. Some browsers will interpret all two digit years as 19xx, so new Date('1/1/49') gives January 1st, 1949, and new Date('1/1/50') gives January 1st, 1950. Others use 1950 as the "two digit year cutoff date", so new Date('1/1/49') gives January 1st, 2049, and new Date('1/1/50') gives January 1st, 1950.

Two Digit Years in JavaScript - Chris Bristol

You have to bear in mind that the RFC document you've referenced was published in April 2001. The 1900s had only just ended. I guess in an attempt to modernise dates away from the 1900s, some browsers now map 0 to 49 as 2000 to 2049. 50, however, still gets mapped as 1950.

The article quoted above also goes on to give some test results:

Here is a brief summary of the results:

  • IE9: No two digit year cutoff found. Year 00 = 1900.
  • Chrome 24.0: Two digit years change between 49 and 50. Year 00 = 2000.
  • Opera: No two digit year cutoff found. Year 00 = 1900.
  • Firefox: No two digit year cutoff found. Year 00 = 1900.
  • Safari: Two digit years change between 49 and 50. Year 00 = 2000.

The article is quite dated now though, so I imagine the data for Opera and Firefox above may have changed.

Upvotes: 4

Related Questions