简体   繁体   English

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

[英]Getting the timezone a simplified ISO 8601 date string

I have two date strings, each in a different time zone. 我有两个日期字符串,每个在不同的时区。 These strings are in what I believe is referred to as "simplified" ISO 8601 format. 我相信这些字符串是所谓的“简化” ISO 8601格式。 Two example dates are listed below. 下面列出了两个示例日期。

  • 2017-08-14T18:41:52.793Z
  • 2017-08-14T23:41:52.000Z

The first date is in CDT while the second date is in UTC. 第一个日期在CDT中,而第二个日期在UTC中。 I believe the last four digits of each of these strings indicates the time zone. 我相信每个字符串的最后四位数字表示时区。

What's weird is when I set up new Date() for each of these, I'm getting incorrect dates reported via console.log() . 奇怪的是,当我为每一个设置new Date() ,通过console.log()报告的日期不正确。 For example: 例如:

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);

Outputs: 输出:

local_date = Mon Aug 14 2017 13:41:52 GMT-0500 (Central Daylight Time) local_date = 2017年8月14日星期一13:41:52 GMT-0500(中部夏令时)
remote_date = Mon Aug 14 2017 18:41:52 GMT-0500 (Central Daylight Time) remote_date = 2017年8月14日星期一18:41:52 GMT-0500(中部夏令时)

It appears as though the first date is getting 5 hours subtracted even though the source date was provided in CDT; 即使在CDT中提供了原始日期,似乎也将第一个日期减去了5小时。 it's like it's assuming that both dates are provided in UTC. 就像假设两个日期都以UTC提供一样。

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

What am I don't wrong here? 我在这里没错吗?

The last digits, as already explained in @Stephen's answer , are the milliseconds. @Stephen的答案中所述,最后一位是毫秒。 So, 52.793 means 52 seconds and 793 milliseconds . 因此, 52.793表示52秒和793毫秒

Both dates are in UTC, because the Z in the end is the UTC designator . 这两个日期使用UTC,因为最后的ZUTC标记

Central Daylight Time (CDT) is 5 hours behind UTC, so you should use -05:00 instead of Z : 中央夏令时(CDT)比UTC晚5个小时,因此您应使用-05:00而不是Z

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

Note: short names like CDT and CST are not real timezones. 注意: CDTCST类的短名称不是实时时区。 They are abbreviations used by more than one timezone . 它们是多个时区使用的缩写。

That's because a timezone is a set of all offsets that a region had, has and will have during its history. 这是因为时区是一个区域在其历史期间拥有,拥有和将要拥有的所有偏移量的集合。 Different regions adopted CST (Central Standard Time) and CDT (Central Daylight Time) at different times, so their history of offsets are not the same. 不同地区在不同时间采用CST (中部标准时间)和CDT (中部夏令时),因此它们的偏移量历史也不相同。 That's why there are so many timezones, and the fact that all use CST/CDT today doesn't mean that all used nor will use the same forever. 这就是为什么有这么多时区的原因,而今天所有人都使用CST / CDT的事实并不意味着所有人都将永远使用相同的时间。

The ideal is to always work with IANA timezones names (always in the format Region/City , like America/Chicago or Europe/Berlin ). 理想的做法是始终使用IANA时区名称 (始终采用Region/City格式,例如America/ChicagoEurope/Berlin )。 Avoid using the 3-letter abbreviations (like CST or PST ) because they are ambiguous and not standard . 避免使用3字母缩写(例如CSTPST ),因为它们是模棱两可的,不是标准的

Unfortunately, plain javascript doesn't have a great support to timezones, but you can use momentjs timezone to deal with it. 不幸的是,普通的javascript对时区没有很好的支持,但是您可以使用momentjs时区来处理它。

If the date and time are in a specific timezone, you could do: 如果日期和时间在特定时区,则可以执行以下操作:

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

This will result in a date equals to 2017-14-08T18:41:52.793-05:00 (CDT). 这将导致日期等于2017-14-08T18:41:52.793-05:00 (CDT)。

The great advantage of using a full timezone name (like America/Chicago ) is that Daylight Saving Time effects are handled automatically. 使用完整的时区名称(例如America/Chicago )的最大好处是可以自动处理夏令时效果。 If I take a date in January, when DST is not in effect: 如果我将日期设置为1月,而DST则无效:

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

The result is a date equivalent to 2017-14-01T18:41:52.793-06:00 (CST). 结果是等于2017-14-01T18:41:52.793-06:00 (CST)的日期。 Note that the offset changed automatically to -06:00 , because in January DST is not in effect in Chicago timezone. 请注意,偏移量自动更改为-06:00 ,因为在一月份,DST在芝加哥时区中无效。 This automatic behaviour is not possible using fixed offsets. 使用固定偏移量无法实现这种自动行为。

You can get a list of all timezones (and choose accordingly) using moment.tz.names() . 您可以使用moment.tz.names()获得所有时区的列表(并进行相应选择moment.tz.names()

The last four digits are 3 digit milliseconds followed by the timezone, where Z indicates UTC time, and +hh:mm and -hh:mm indicates the offset from UTC time. 最后四位数字是3位数毫秒,后跟时区,其中Z表示UTC时间, +hh:mm-hh:mm表示距UTC时间的偏移量。

So 793Z is 793 milliseconds in UTC. 因此793Z是UTC的793毫秒。

So both of your examples are in UTC, which is why you're seeing the output you're seeing. 因此,您的两个示例都使用UTC,这就是为什么您看到自己看到的输出的原因。

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

Would be CDT format. 将是CDT格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM