识别 ISO 8601 中的时区
Posted
技术标签:
【中文标题】识别 ISO 8601 中的时区【英文标题】:Identifying time zones in ISO 8601 【发布时间】:2017-06-30 21:05:20 【问题描述】:不,我不是在谈论区域偏移 --- 这些偏移在一年中可能会因地区而异,例如夏令时。我说的是实际的time zones maintained by IANA。我知道 ISO 8601 不支持这些,对吗?
平台采取了哪些措施来支持在类似 ISO 8601 的字符串表示中识别时区?我注意到最新的 Java 日期/时间库为此使用了扩展的 ISO 8601 格式,例如2011-12-03T10:15:30+01:00[Europe/Paris]
。 (见DateTimeFormatter API。)
是否有一些融合约定(例如与其他语言和平台)来扩展 ISO 8601 以支持时区指定?
【问题讨论】:
第二个要点使这个问题相当广泛。 我阅读the W3C description 的方式似乎是正确的:ISO 8601 支持区域偏移,但不支持具有可变偏移的时区(通常是夏令时的时区,适用于许多 IANA 时区) . @OleV.V.您链接的 W3C Note 文档只是实际 ISO 8601 标准的简要概要。我建议阅读优秀的Wikipedia article on ISO 8601 和week date,也许还有draft of the standard(官方标准在付费墙后面)。 我只想指出,我很惊讶,在赏金到期时,所有这些人和所有这些 cmets 都可以想出图书馆的另一个例子/平台(@MattJohnson 提到节点时间)以字符串格式包含时区! 【参考方案1】:更新:
现在有一个 IETF 提案草案,以使用方括号中的时区标识符扩展 RFC3339,其中包括:https://github.com/ryzokuken/draft-ryzokuken-datetime-extended
原答案:
我知道 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-like 日期时间格式化程序...
...扩展 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)
(这是野田时间的默认设置)
如果您正在寻找一种以标准化方式在 API 中包含 ZonedDateTime
或类似数据的方法,我个人的建议是在单独的字段中传递时区名称。这样,数据的每个部分都尽可能好。例如在 JSON 中:
"timestamp": "2011-12-03T10:15:30+01:00",
"timezone": "Europe/Paris"
【讨论】:
“究竟支持什么?你的这部分问题不清楚。”好吧,我想我把它放在标题中......但很公平---我已经更新了这个问题。 “如果您的意思是支持 ISO-8601 日期时间偏移 + 时区 ID 的字符串表示,那么有些平台有这个,有些则没有。”嗯,这就是我要问的问题。其他平台在做什么?我希望有人能给我一些其他的例子,这样我就可以知道 Java 是独自一人,还是它正在遵循一些趋同的趋势。 另外,听起来您正在寻找的是 RFC。也许你应该提出一个? :) 嘿,我刚刚发现there's a draft for ISO8601-2 "extentions" in the works at ISO,当然我立刻想到了你。也许你可以联系他们建议包括这个? :) 仅供参考 - 如果你想加入,我开始了一个 Twitter 线程 here。:) @GarretWilson - 仅供参考 - 现在有一个 IETF 提案草案,以使用方括号中的时区标识符扩展 RFC3339,除其他外:github.com/ryzokuken/draft-ryzokuken-datetime-extended【参考方案2】: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/Longyearbyen
和 Europe/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 视为 One-True-Time,分区或偏移值只是变化。
【讨论】:
大体上同意在可能的情况下使用 UTC 的建议。然而,有些用例很尴尬:如果逻辑必须引用过去或未来的任意事件,其唯一时间信息在本地区域,那么 UTC 转换并不明显。 (例如,纽约证券交易所将在 10 年后 3 月的第二个星期二几点开市?在当地时间,很可能是美国东部时间上午 9:30,但 UTC 取决于 DST 转换——即使这也取决于规则在此之前不会改变。)因此,在这种情况下,最好有一个标准来表示本地分区时间。 @Sumitsu 我完全同意,100%。我强调相反的立场,因为我发现程序员倾向于 (a) 让自己发疯地转换进出他们自己的狭隘时区,并且 (b) 认为(祈祷?)使用“本地”(未分区)日期时间值将以某种方式使他们免于处理时区问题。但正如你所说,LocalDateTime
在许多情况下肯定很有用,尤其是像纽约证券交易所开市这样的应用程序,因为政客如此频繁、如此粗心、如此迅速地重新定义时区。例如,就在去年,土耳其决定只使用 DST 几周警告。
只是 TZ 偏移量允许收集 一些 客户端相对值。虽然在其他用途上不如 TZ 名称那么强大,但它确实提供了一小步.. 主要是(在 99% 的情况下,在 记录时)允许“一天”不同于在“单个标量”中同时捕获两者的时间。 TZ 偏移确实具有优于 TZ 名称的好属性,因为它是到 UTC 的纯映射,尽管能够也以这种“单标量”形式捕获 TZ 名称会很好以实现未来改进的处理:
..而纯 UTC 时间方法经常会错过“一天”的纯粹概念。然而,对于生活的许多方面,所有相关的是日期和相对时间。在这种常见的情况下,这一天是否在一年中从“实时”前后跳动并不重要。
以上是关于识别 ISO 8601 中的时区的主要内容,如果未能解决你的问题,请参考以下文章