2017-02-12 113 views
13

不,我不是在谈论区域偏移量---这些偏移量可能会在一年中因某个地区而异。 DST。我在谈论实际的time zones maintained by IANA。我明白这些是由ISO 8601支持的而不是,对吗?识别ISO 8601中的时区

什么是平台在ISO 8601类似的字符串表示中支持识别时区?我注意到最新的Java日期/时间库为此使用了扩展的ISO 8601格式。 2011-12-03T10:15:30+01:00[Europe/Paris]。 (请参阅DateTimeFormatter API。)

是否存在一些用于扩展ISO 8601以支持时区指定的聚合约定(例如,与其他语言和平台)?

+0

第二个问题点使这个问题相当广泛。 – chrylis

+0

我读[W3C说明](https://www.w3.org/TR/NOTE-datetime)的方式似乎是正确的:ISO 8601支持区域偏移,但不支持具有可变偏移量的时区(通常为时区夏季时间,这适用于许多IANA时区)。 –

+1

@ OleV.V。您链接的W3C Note文档仅仅是实际ISO 8601标准的简要摘要。我建议阅读[ISO 8601维基百科文章](https://en.wikipedia.org/wiki/ISO_8601)和[星期日期](https://en.wikipedia.org/wiki/ISO_week_date)上的优秀文章,以及也许是[标准草案](https://duckduckgo.com/?q=ISO+8601+draft&t=osx&ia=web)(官方标准在付费墙后面)。 –

回答

13

我明白这些不受ISO 8601支持,对吗?

正确。 ISO-8601不关注时区标识符。 IANA/Olson TZ名称不是“标准”。他们只是我们拥有的最可靠的东西。 (有些人可能会认为他们的事实上标准。)

什么平台做支持呢?

支持什么?你的问题的这一部分不清楚。如果您的意思是支持IANA时区,那就到处都是。有些平台将它们内置,有些依赖于库。如果您的意思是支持ISO-8601日期 - 时间偏移+时区ID的字符串表示形式,则某些平台具有此功能,有些则不具备此功能。如果你想知道更多,你必须更具体。

我注意到最新的Java日期/时间库为此使用了扩展的ISO 8601格式, 2011-12-03T10:15:30 + 01:00 [欧洲/巴黎]。 (请参阅DateTimeFormatter API。)

我想你说的是DateTimeFormatter.ISO_ZONED_DATE_TIME。该文档明确说:

的ISO- 日期 - 时间格式...

...扩展了ISO-8601扩展偏移日期时间格式添加的时区。方括号中的部分不是ISO-8601标准的一部分。

所以这是Java的特定格式,而不是标准。

对于扩展ISO 8601以支持时区指定,是否存在一些会聚惯例(例如与其他语言和平台)?

据我所知,目前还没有标准将ISO8601时间戳和IANA时区标识符合并为一种格式。一个可以代表很多不同的方式,包括:

  • 2011-12-03T10:15:30+01:00[Europe/Paris](这是Java 8中默认)
  • 2011-12-03T10:15:30+01:00(Europe/Paris)
  • 2011-12-03T10:15:30+01:00 Europe/Paris
  • 2011-12-03T10:15:30+01:00 - Europe/Paris
  • 2011-12-03T10:15:30+01:00/Europe/Paris
  • 2011-12-03T10:15:30+01:00|Europe/Paris
  • 2011-12-03T10:15:30 Europe/Paris (+01) (这是N中的默认值oda时间)

如果您正在寻找的是以标准方式在API中包含ZonedDateTime或类似数据的方式,我个人的建议是将时区名称传递到单独的字段中。这样,数据的每个部分都是尽可能好的。例如在JSON中:

{ 
    "timestamp": "2011-12-03T10:15:30+01:00", 
    "timezone": "Europe/Paris" 
} 
+0

另外,有趣的是,顶部的[Java ZonedDateTime文档](https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html)使用了带空格分隔符的格式的括号内。 ;) –

+0

“支持到底是什么?你的问题的这一部分不清楚。”那么,我认为我把它放在标题中......但是很公平 - 我已经更新了这个问题。 “如果您的意思是支持ISO-8601日期 - 时间偏移+时区ID的字符串表示形式,则某些平台具有此功能,有些则不具备此功能。”那是我问的问题。其他平台在做什么?我希望有人能给我一些其他的例子,所以我可以知道Java是否是单独的,或者它是否正在遵循一些趋同的趋势。 –

+0

“人们可以用许多不同的方式来表达......”的确,@MattJohnson,我可以整天坐在这里发明数百种表示时区的可能变化形式。问题在于是否存在一些新兴的共识,甚至是Java方法以外的其他“在野外”使用的例子。 –

9

Answer by Matt Johnson是正确的。我只想补充一些想法。

时区随偏移从 - UTC

一个offset-from-UTC仅仅是若干小时,分钟和秒超前/落后UTC。独自一人,这确实在时间线上的某个特定时刻进行日期。但它不像包含official time zone name那样具有信息量。

虽然目前还没有包含时区名称的标准,但我确实希望其他人遵循java.time类的主角,在方括号中附加时区名称。这种格式对我来说似乎很明智,因为截断方括号部分以便与非智能软件向后兼容很简单。

例如:
2011-12-03T10:15:30+01:00[Europe/Paris]。如果数据仅为2011-12-03T10:15:30+01:00,我们将能够确定时间线上的时刻,但无法将其他时刻调整到同一个思维模式,因为我们不知道应该采用哪些调整规则。诸如Europe/Zagreb,Africa/Brazzaville,Arctic/LongyearbyenEurope/Isle_of_Man之类的区域全部共享+01:00的偏移量,但它们可能具有与Europe/Paris不同的其他调整。因此,如果您尝试将价值增加三天至2011-12-03T10:15:30+01:00,那么您确实无法如实计算结果,因为您不知道可能需要进行哪些调整,例如可能在这三天内发生的DST切换。

时区定义了一组处理异常的规则,如Daylight Saving Time (DST)。世界各地的政治家都喜欢调整他们的时区,甚至重新定义他们的时区。所以这些规则经常变化。将时区看作随着时间推移的偏移集合,历史中的许多时间段,其中每个时期在该特定区域中具有特定的偏移量。

您可以将时区视为从UTC时间点开始的偏移量的集合。在America/Los_Angeles今年的部分时间比UTC落后8小时,部分时间会比UTC晚7个小时。这使得2点数据作为该时区的一部分被收集。

另一个例子,在过去的几年中,土耳其每年的部分时间比UTC提前2个小时,每年的部分时间提前3个小时。 2016年,这改变了无限期地提前3小时。因此,时区Europe/Istanbul中的多个数据点。

只需使用UTC

我个人不中即使使用的值,如2011-12-03T10:15:30+01:00看多的价值。如果没有时区,您也可以单独使用UTC。在这种情况下,2011-12-03T09:15:30Z(上午9点而不是上午10点)。

通常最好的做法是在存储和交换日期时间值时使用UTC。 将UTC视为一次真实时间,分区或偏移值仅仅是变化。

+0

尽可能同意使用UTC的建议。但是,某些用例很尴尬:如果逻辑必须引用过去或未来的任意事件,而唯一的时间信息位于本地区域中,则UTC转换不明显。 (例如,纽约证券交易所将在三月的第二个星期二的什么时间,10年后开放?在当地时间,ET很可能是上午9:30,但UTC取决于DST转换 - 甚至这取决于规则在此之前不会改变)。因此,在这种情况下,最好有一个用于表示本地分区时间的标准。 – Sumitsu

+1

@Sumitsu我完全同意,100%。我强调相反的立场,因为我发现程序员倾向于:(a)让自己坚持转换进出自己的狭隘时区,(b)认为(祈祷)使用“本地”(未分区)日期时间值将以某种方式使他们不必处理时区问题。但正如你所说,LocalDateTime在很多情况下都是有用的,特别是像纽约证券交易所开盘这样的应用程序,因为政治家经常如此不经意地如此迅速地重新定义时区。例如,就在去年,土耳其决定停留在夏令时,只有几个星期的警告。 –

+0

只要TZ-offset允许收集*一些*客户相对值。虽然不如TZ的名字其他用途强壮,它确实提供了一小步......主要是(在99%的情况下,在*时间的录音*),允许一个“日”与时间截然不同,同时捕获在“单个标量”内。 TZ-offset在TZ名称上具有很好的属性,因为它是纯粹映射到UTC的,虽然能够*还*以这种'单一标量'形式捕获TZ名称将很好,以便将来改进处理:} – user2864740