Javascript Dates, Y2K etc.


The treatment of the year value in Javascript dates is incompatible between Netscape 4 (Javascript 1.3 and ECMAScript) on the one hand, and Netscape 3 (Javascript 1.2) on the other hand. The question then arises, whether we can deduce the correct year from the value of date.getYear(), without needing to know which version of Javascript we're dealing with. Netscape 2 just covers a restricted date range, and needs no additional consideration here re. coding.

It's amusing that many of the free "cargo cult" Javascripts found on the web, despite their baroque complexity, don't work for even one version of Javascript, outside of the range 1970-1999, presumably because the authors couldn't be bothered to RTFM before starting to write their code.

Of course, the actual problem goes away in Netscape 4/ECMAScript, because you can use getFullYear to get a clearly defined answer. But if we want the code to run without modifications or extra tests on NS3 (and NS2 where applicable), this would not do.

A pertinent answer is given in the Javascript FAQ and, I'm tickled to see, gives the same getYear()-based solution that I deduced for myself.

What the specs say

Netscape 3 (Javascript 1.2):

The getYear method returns either a 2-digit or 4-digit year:
For years between and including 1900 and 1999, the value returned by getYear is the year minus 1900. For example, if the year is 1976, the value returned is 76.
For years less than 1900 or greater than 1999, the value returned by getYear is the four-digit year. For example, if the year is 1856, the value returned is 1856. If the year is 2026, the value returned is 2026.

Netscape 4 (ECMAScript, Javascript 1.3)

Year minus 1900


I don't see any mention of years BC, so it's possible that they aren't dealt with; any attempt to deal with them would mean that you couldn't tell the difference between say 1800 (for which Netscape 4 would return a getYear of -100) and a certain year BC (for which Netscape 3 would presumably return -100, though I don't find this actually documented). So let's exclude years BC from our consideration.

Also, I've made no attempt to consider what happened as a result of the calendar change in 1752 (nor any calendar changes before that). John Stockton commented on Usenet:

1582/3 is not special to javascript; nor is 1752 (except that javascript can represent dates which did not occur everywhere).

Netscape documentation for Netscape 3, as already noted, says that except for years 1900-1999, it returns a "4-digit" year. This seems to limit the range of applicability to the years 1000-9999AD. There is no clear statement of what happens for years outside this range. So let's exclude those from our considerations too.

On that basis:

Let's set an upper cutoff year of 2899. Then values of getYear of 2000 upwards can only occur with JS1.2 and we don't add 1900.

To cut a long story short: if we test getYear against 1000, then lower values (i.e 0-999 and negative values) should have 1900 added to them, whereas other values should be left unchanged. This will then cover the period AD1000 to 2899, assuming that browsers behave as documented. If the answer lies outside of this range then it could be incorrect (although it might be correct, but we'd need to check the version to find out). However, you might want to avoid tangling with dates in 1752 or earlier, to avoid needing to understand possible issues from calendar change(s)!

Final remarks

OK, this was just a bit of pedantic fun. Anyone spot any errors in the logic? Please let me know.

|Up| |RagBag|About the author|