Tips for working with Pre-1000 A.D. Dates in JavaScript

You have to set the year again, like setFullYear() or setUTCFullYear(). The Date can store 285 616 years before and after 1. 1. 1970.

var d = new Date( 0000, 1, 29 );       // Thu Mar 01 1900 00:00:00 GMT+0100
d.setFullYear(-0004);                  // Wed Mar 01 -0004 00:00:00 GMT+0057
d.setFullYear( 0000, 1, 29 );          // Tue Feb 29 0000 00:00:00 GMT+0057
                                       // Yes, year zero was a leap year

Explanation:

  1. new Date( year [4-digit number, 0–99 map to 1900–1999], month [0-11], day [def. 1], hours, minutes, seconds, milisecs ); is same like Date.UTC but in local timezone.
  2. hours, minutes and seconds will be automatically filled with zeros.
  3. the year lower than 1900 is converted to 1900 by default.
  4. the year 1900 is not a leap year, so it is shifted to next closest day 1. Mar.
  5. so, we have to set the year to zero 0000 again (year always must be min. 4-digit in this case), month and day. We use setFullYear() method with optional parameters for month and day; then if the year will be a leap year, it won’t be shifted.

i prefer:

var d = new Date(Date.UTC(year, month, day, hour, min, sec, 0));
d.setUTCFullYear(year);

this always works for all supported year values.

the setUTCFullYear() call fixes JavaScript's intentional bug if you ask me.


Have you tried using the setUTC... functions on a date object after its creation?

setUTCDate()
setUTCFullYear()
setUTCMonth()
setUTCHours()
setUTCMinutes()
setUTCSeconds()