Jac*_*Dev 1 javascript datetime date iso8601 timezone-offset
我有两个日期字符串,每个字符串位于不同的时区。我认为这些字符串采用“简化”ISO 8601 格式。下面列出了两个示例日期。
2017-08-14T18:41:52.793Z2017-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);
Run Code Online (Sandbox Code Playgroud)
输出:
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/
我在这里没有错什么?
小智 6
正如@Stephen 的回答中已经解释的那样,最后的数字是毫秒。所以,52.793意味着52 秒和 793 毫秒。
两个日期均采用UTC 格式,因为Z最后的 是UTC 指示符。
-05:00中部夏令时间 (CDT)比UTC 晚 5 小时,因此您应该使用Z:
new Date("2017-08-14T18:41:52.793-05:00")
Run Code Online (Sandbox Code Playgroud)
注意:简称,如CDT和CST不是真正的时区。它们是多个时区使用的缩写。
这是因为时区是一个地区在其历史上曾经、现在和将来的所有偏移量的集合。不同地区采用CST(中部标准时间)和CDT(中部夏令时间),因此它们的偏移历史并不相同。这就是为什么有如此多的时区,并且今天所有时区都使用 CST/CDT 的事实并不意味着所有时区都使用或将永远使用相同的时区。
理想的情况是始终使用IANA 时区名称Region/City(始终采用America/Chicago或 等格式Europe/Berlin)。避免使用 3 个字母的缩写(如CST或PST),因为它们不明确且不标准。
不幸的是,普通的 javascript 对时区没有很好的支持,但是你可以使用momentjs timezone来处理它。
如果日期和时间位于特定时区,您可以执行以下操作:
moment.tz('2017-08-14T18:41:52.793', 'America/Chicago')
Run Code Online (Sandbox Code Playgroud)
这将导致日期等于2017-14-08T18:41:52.793-05:00(CDT)。
使用完整时区名称(如America/Chicago)的巨大优势是自动处理夏令时效果。如果我选择一月份的日期,此时 DST 尚未生效:
moment.tz('2017-01-14T18:41:52.793', 'America/Chicago')
Run Code Online (Sandbox Code Playgroud)
结果是一个日期相当于2017-14-01T18:41:52.793-06:00(CST) 的日期。请注意,偏移量自动更改为-06:00,因为 1 月 DST 在芝加哥时区不生效。使用固定偏移量不可能实现这种自动行为。
您可以使用 获取所有时区的列表(并进行相应选择)moment.tz.names()。