Tips for working with Pre-1000 A.D. Dates in JavaScript
I'm curious if anyone has any good solutions for accurately building dates prior to the year 1000 A.D. - particularly the years 1 - 100 AD.
For example, if I want to build a date for the start of the 1st millenium, I can'开发者_JAVA百科t just do...
new Date(Date.UTC(1,0,1,0,0,0,0));
because it tries to be "smart" and assume that 1 is 1901, which gives me...
Sun Dec 31 1900 18:00:00 GMT-0600 (CST)
The same thing goes for the year 99...
new Date(Date.UTC(99,0,1,0,0,0,0));
which becomes
Thu Dec 31 1998 18:00:00 GMT-0600 (CST)
Thoughts?
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()
Here is the basic solution I came up with. If a date is prior to year 1000, I just add a 1000 to it while constructing the date, then use setUTCFullYear()
afterwards.
if (year >= 0 && year < 1000) {
var d = new Date(Date.UTC(year + 1000,mon,day,hour,min,sec,0));
d.setUTCFullYear(d.getFullYear() - 1000);
return d;
}
1000 may be overkill since I was only having problems with pre-100 dates... but, whatever.
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:
- 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.
- hours, minutes and seconds will be automatically filled with zeros.
- the year lower than 1900 is converted to 1900 by default.
- the year 1900 is not a leap year, so it is shifted to next closest day 1. Mar.
- 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.
It's exactly what Date.UTC
and the Date
constructor function (called with numbers as arguments) are supposed to do. A simple workaround is to use Date.parse
, which will not apply any corrections
new Date(Date.parse('0001-01-04'));
new Date(Date.parse('0001-01-04T18:00:00Z'));
Make some arbitrary date d
and call d.setUTCFullYear(myDate)
. This seems to be working for me in Chrome's console.
Others have provided hints at a fix. The javascript date object was copied from Java, so has all its bugs too. There is not much point to Gregorian dates before 1582 anyway since before that various other calendars were in use.
精彩评论