It's complicated and inconsistent, yes. The JavaScript Date object was based in Java 1.0, which is so bad that Java has redesigned a completely new package. JavaScript is not so lucky.
- Date is based on unix eopch because it is defined . Internal details.
1st Jan 1970 is the actual time of this baseline.since is the direction of the timestamp value: forward for + ve, backward for -ve.- Externally, the Date constructor has several different ways of using based on parameters:
Zero parameters = current time
new Date()
The time is absolute, but the “displayed” time zone can be UTC or local.
For simplicity, only UTC will be used in this answer. Keep time zone when testing.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z. new Date(100) // 100ms from 1970 baseline. new Date(-10) // -10ms from 1970 baseline.
new Date('000') // Short years are invalid, need at least four digits. new Date('0000') // 0000-01-01. Valid because there are four digits. new Date('1900') // 1900-01-01. new Date('1900-01-01') // Same as above. new Date('1900-01-01T00:00:00') // Same as above. new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, etc. @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z. new Date(0,0,1) // Same as above. Date is 1 based. new Date(0,0,0) // 1 day before 1900 = 1899-12-31. new Date(0,-1) // 1 month before 1900 = 1899-12-01. new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30. new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29. new Date('0','1') // 1900-02-01. Two+ params always cast to year and month. new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900. new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative Year = BC
new Date(-1,0)
No 0 AC. There is 1 AC and a year up to 1 BC. Year 0 by agreement 1 BC.
2 BC is displayed as the year "-000001" . Extra zeros are required because it is outside the normal range (0000 to 9999). If you are new Date(12345,0) , you will get "+012345-01-01" too.
Of course, the Gregorian calendar , adopted back in 1923 in Europe, will cease to be significant long before we reach BC. In fact, scholars accept that Jesus was not born in 1 BC. But with the stars and Earth moving along this scale path, the calendar is the least of your worries.
The remaining code is just a variation of these cases. For instance:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970 new Date('0100') // One string = iso = 0100-01-01. new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
I hope you enjoyed it. Please do not forget to vote. :)
To keep working, save all dates in ISO 8601 and use the string constructor.
And if you need to process the time zone, save all dates in UTC.