获取时区简化的 ISO 8601 日期字符串
Getting the timezone a simplified ISO 8601 date string
我有两个日期字符串,每个都在不同的时区。这些字符串采用我认为称为 "simplified" 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 = 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,因为最后的 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.
不幸的是,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()
.
获取所有时区的列表(并相应地选择)
我有两个日期字符串,每个都在不同的时区。这些字符串采用我认为称为 "simplified" 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 = 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,因为最后的 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.
不幸的是,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()
.