使时区成为简化的ISO 8601日期字符串

时间:2017-08-14 19:04:48

标签: javascript date datetime iso8601 timezone-offset

我有两个日期字符串,每个日期字符串位于不同的时区。这些字符串在我认为被称为"简化" 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/

我在这里做错了什么?

2 个答案:

答案 0 :(得分:4)

最后的数字,如@Stephen's answer中所述,是毫秒。因此,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

不幸的是,普通的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格式。