我有两个日期字符串,每个日期字符串位于不同的时区。这些字符串在我认为被称为"简化" ISO 8601格式。下面列出了两个示例日期。
2017-08-14T18:41:52.793Z
2017-08-14T23:41:52.000Z
第一个日期是CDT,第二个日期是UTC。我相信每个字符串的后四位数字表示时区。
当我为每个设置new Date()
时,我感到很奇怪,我通过console.log()
报告的日期不正确。例如:
const local_date = new Date("2017-08-14T18:41:52.793Z");
const remote_date = new Date("2017-08-14T23:41:52.000Z");
console.log("local_date = " + local_date);
console.log("remote_date = " + remote_date);
输出:
local_date = 2017年8月14日星期一13:41:52 GMT-0500(中部夏令时)
remote_date = 2017年8月14日星期一18:41:52 GMT-0500(中部夏令时)
即使源日期是在CDT中提供的,似乎第一个日期减去了5个小时;它假设两个日期都以UTC格式提供。
https://jsfiddle.net/nkax7cjx/1/
我在这里做错了什么?
答案 0 :(得分:4)
最后的数字,如@Stephen's answer中所述,是毫秒。因此,52.793
表示 52秒和793毫秒。
UTC中的两个日期 ,因为最后的Z
是UTC designator。
中部夏令时(CDT)比UTC晚5个小时,因此您应该使用-05:00
代替Z
:
new Date("2017-08-14T18:41:52.793-05:00")
注意:CDT
和CST
等短名称不是真正的时区。它们是缩写used by more than one timezone。
这是因为时区是一个区域在其历史中拥有,拥有和将拥有的所有偏移的集合。不同地区在不同时间采用CST
(中央标准时间)和CDT
(中部夏令时),因此他们的偏移历史不同。这就是为什么有这么多的时区,而今天所有使用CST / CDT的事实并不意味着所有使用过的也不会永远使用它们。
理想情况是始终使用IANA timezones names(始终采用Region/City
格式,例如America/Chicago
或Europe/Berlin
)。
避免使用3个字母的缩写(例如CST
或PST
),因为它们是ambiguous and not standard。
不幸的是,普通的javascript对时区没有很好的支持,但您可以使用momentjs timezone来处理它。
如果日期和时间在特定时区,您可以执行以下操作:
moment.tz('2017-08-14T18:41:52.793', 'America/Chicago')
这将导致日期等于2017-14-08T18:41:52.793-05:00
(CDT)。
使用完整时区名称(如America/Chicago
)的巨大优势是夏令时效果会自动处理。如果我在1月份的日期,当夏令时没有生效时:
moment.tz('2017-01-14T18:41:52.793', 'America/Chicago')
结果是相当于2017-14-01T18:41:52.793-06:00
(CST)的日期。请注意,偏移自动更改为-06:00
,因为1月份DST在芝加哥时区不起作用。使用固定偏移无法实现此自动行为。
您可以使用moment.tz.names()
获取所有时区的列表(并相应地选择)。
答案 1 :(得分:2)
最后四位是3位数毫秒,后跟时区,其中Z表示UTC时间,HTTP/1.1 200 OK
Date: Mon, 14 Aug 2017 19:12:17 GMT
Server: Jetty(9.4.4.v20170414)
Transfer-Encoding: chunked
spark.Response@592d7509
和+hh:mm
表示与UTC时间的偏移量。
所以793Z是UTC的793毫秒。
所以你的两个例子都是UTC,这就是你看到你看到的输出的原因。
-hh:mm
将是CDT格式。