获取时区简化的 ISO 8601 日期字符串

Getting the timezone a simplified ISO 8601 date string

我有两个日期字符串,每个都在不同的时区。这些字符串采用我认为称为 "simplified" ISO 8601 的格式。下面列出了两个示例日期。

第一个日期是 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 = Mon Aug 14 2017 13:41:52 GMT-0500 (Central Daylight Time)
remote_date = Mon Aug 14 2017 18:41:52 GMT-0500 (Central Daylight Time)

尽管 CDT 中提供了源日期,但第一个日期似乎减去了 5 小时;这就像假设这两个日期都以 UTC 格式提供。

https://jsfiddle.net/nkax7cjx/1/

我没看错什么?

后四位为3位毫秒后跟时区,其中Z表示UTC时间,+hh:mm-hh:mm表示与UTC时间的时差。

所以 793Z 在 UTC 中是 793 毫秒。

所以你的两个例子都是 UTC,这就是你看到你看到的输出的原因。

const local_date = new Date("2017-08-14T18:41:52.793-05:00");

将是 CDT 格式。

正如 中所解释的那样,最后一位数字是毫秒。因此,52.793 表示 52 秒和 793 毫秒

两个日期 都是 UTC,因为最后的 ZUTC designator.

中部夏令时 (CDT) 比 UTC 晚 5 小时,因此您应该使用 -05:00 而不是 Z:

new Date("2017-08-14T18:41:52.793-05:00")

注意:像 CDTCST 这样的短名称不是真正的时区。它们是缩写 used by more than one timezone.

那是因为时区是一个地区在其历史上曾经、曾经和将要拥有的所有偏移量的集合。不同地区在不同时间采用CST(中部标准时间)和CDT(中部夏令时),因此它们的偏移历史是不一样的。这就是为什么有这么多时区,今天所有人都使用 CST/CDT 并不意味着所有人都使用也不会永远使用相同的事实。

理想情况是始终使用 IANA timezones names(始终采用 Region/City 格式,例如 America/ChicagoEurope/Berlin)。 避免使用 3 个字母的缩写(如 CSTPST),因为它们是 ambiguous and not standard.

不幸的是,plain javascript 对时区的支持不是很好,但是你可以使用 momentjs timezone 来处理它。

如果日期和时间在特定时区内,您可以这样做:

moment.tz('2017-08-14T18:41:52.793', 'America/Chicago')

这将导致日期等于 2017-14-08T18:41:52.793-05:00 (CDT)。

使用完整时区名称(如 America/Chicago)的最大优点是自动处理夏令时效果。如果我在一月份约会,那时 DST 还没有生效:

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().

获取所有时区的列表(并相应地选择)