Reputation: 11
new Date("0001-01-01T01:00:00Z")
--> Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
Incorrect GMT: my timezone GMT+3000
, but date creates GMT+0150
Upvotes: 1
Views: 1374
Reputation: 241525
Pac0's answer is correct (and you should accept that answer since it came first, not this one). But just to provide a detailed explanation:
Dates from before recorded history of time zones are marked in the time zone database as LMT
- which stands for Local Mean Time. The offsets are derived from the latitude and longitude of the city, not by any current political determination.
Since the offset shown is 1:50:16
ahead of UTC, I can derive that your system time zone is Europe/Minsk
. This is seen in the tzdb sources here:
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Minsk 1:50:16 - LMT 1880
This is just the first line of the zone entry for Europe/Minsk
, which says that until 1880, use the LMT entry of UTC+1:50:16.
As to why it says "Moscow Standard Time" - that string comes from the Unicode CLDR data, which in the /common/supplemental/metaZones.xml
file we can see:
<timezone type="Europe/Minsk">
<usesMetazone to="1991-03-30 23:00" mzone="Moscow"/>
<usesMetazone to="2011-03-27 00:00" from="1991-03-30 23:00" mzone="Europe_Eastern"/>
<usesMetazone to="2014-10-26 22:00" from="2011-03-27 00:00" mzone="Europe_Further_Eastern"/>
<usesMetazone from="2014-10-26 22:00" mzone="Moscow"/>
</timezone>
So Europe/Minsk
uses the Moscow
metazone up until 1991. Then, using one of the language files such as /common/main/en.xml
for English, we can see the actual text assigned to this metazone:
<metazone type="Moscow">
<long>
<generic>Moscow Time</generic>
<standard>Moscow Standard Time</standard>
<daylight>Moscow Summer Time</daylight>
</long>
</metazone>
And now you have a complete picture for how the string Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
was derived from 0001-01-01T01:00:00Z
.
Upvotes: 2
Reputation: 29002
A timezone is an offset plus a date range. To format your date, javascript wants to know what the timezone offset was for Moscow in the year zero. This is hard information to come by, and might not be accurate ! You think you're asking something simple, but it's actually pretty extreme. If you want to use the date object to represent durations, you should take the epoch as your starting point.
Upvotes: 1
Reputation: 23149
For dates, you can (and should, in my opinion) define them in UTC ISO 8601 "Z" format ("YYYY-MM-DDTHH:MM:SSZ"), just as you did.
However, to get a user-friendly string representation of those dates, it will depend on your client and on the Javascript engine used. You can constrain the output if you explicitly specify a reference timezone with toLocaleString()
.
var date = new Date("1990-01-01T01:00:00Z");
console.log(date.toLocaleString("en-US", {timeZone: "Asia/Jerusalem"}));
console.log(date.toLocaleString("en-US", {timeZone: "Europe/Moscow"}));
console.log(date.toLocaleString("en-US", {timeZone: "Africa/Djibouti"}));
// output on my machine, should be the same on yours :
// 1/1/1990, 3:00:00 AM
// 1/1/1990, 4:00:00 AM
// 1/1/1990, 4:00:00 AM
console.log(date.toString());
// output **on my machine**, should **not** be the same on yours
// Mon Jan 01 1990 02:00:00 GMT+0100 (Central European Standard Time)
For the 16 seconds issue, this is linked to the way offset are defined by the rules for those dates before the notion of IANA timezone existed.
They probably don't make sense in your application, and I discourage you to use dates like 1st January of year 0001 for your examples.
Examples :
var date = new Date("0001-01-01T01:00:00Z");
console.log(date.toLocaleString("en-US", {timeZone: "Asia/Jerusalem"}));
console.log(date.toLocaleString("en-US", {timeZone: "Europe/Moscow"}));
console.log(date.toLocaleString("en-US", {timeZone: "Africa/Djibouti"}));
// output on my machine, should be the same on yours :
// 1/1/1, 3:20:54 AM
// 1/1/1, 3:30:17 AM
// 1/1/1, 3:27:16 AM
console.log(date.toString());
// output **on my machine**, should **not** be the same on yours
// Mon Jan 01 0001 01:09:21 GMT+0009 (Central European Standard Time)
More information here (thanks Johan Karlsson for the link) :
https://bugs.chromium.org/p/chromium/issues/detail?id=849404
The most relevant comment from this link is, I think :
This is working as intended and working per spec. The spec says that we have to follow the IANA timezone database.
In 1880, there's no standard timezone and America/Los_Angeles timezone offset was based on its longitude. The same is true of other timezones.
Also note that there are many timezone around the world the zone offset (and whether or not to have DST or when to start DST) have changed multiple times even since 2000 (e.g. Europe/Moscow). The change to make them work correctly also brought in what's reported here.
Upvotes: 2