在ISO 8601中识别时区

47
不,我所讲的不是区域偏移量——这些可能因为夏令时等原因在一年中会有所变化。我指的是由 IANA 维护的实际时区。我知道这些并没有被 ISO 8601 支持,这是正确的吗?
平台们都在做些什么来支持在类似于 ISO 8601 的字符串中识别时区?我注意到最新的 Java 日期/时间库正在使用扩展的 ISO 8601 格式来表示,例如2011-12-03T10:15:30+01:00[Europe/Paris]。(请参见DateTimeFormatter API。)
是否有一些汇合的约定(例如与其他语言和平台),以扩展 ISO 8601 来支持时区指定?

第二个要点使得这个问题变得相当宽泛。 - chrylis -cautiouslyoptimistic-
根据我阅读W3C描述的方式,你似乎是正确的:ISO 8601支持区域偏移量,但不支持具有可变偏移量的时区(通常是具有夏令时的时区,这适用于许多IANA时区)。 - Ole V.V.
1
@OleV.V. 你提供的 W3C Note 文档只是 ISO 8601 标准的简要概述。我建议阅读优秀的 维基百科 ISO 8601 文章周日期,或许还有一份标准草案(正式标准需要付费才能获取)。 - Basil Bourque
我只想指出,当赏金到期时,所有这些人和所有这些评论只能提供另一个库/平台的唯一示例(@MattJohnson提到了Node Time),该示例以字符串格式包含时区,这让我感到惊讶! - Garret Wilson
2个回答

37

更新:

现在有一份IETF草案提议扩展RFC3339。其中包括在方括号内添加时区标识符等内容:https://datatracker.ietf.org/doc/draft-ietf-sedate-datetime-extended/

原始回答:

我了解这些不被ISO 8601支持,是吗?

正确。ISO-8601不涉及时区标识符。IANA/Olson TZ名称并非“标准”,而只是我们最可靠的东西。(有人可能认为它们是事实上的标准。)

平台正在做些什么来支持这个吗?

支持什么?你问题的这部分不清楚。如果你是指支持IANA时区,那就随处可见。有些平台内置它们,有些依赖库。如果你是指支持ISO-8601日期时间偏移量+时区ID的字符串表示形式,则某些平台具有此功能,而某些平台则没有。如果想了解更多信息,您需要更具体。

我注意到最新的Java日期/时间库使用了扩展的ISO 8601格式,例如2011-12-03T10:15:30+01:00[Europe/Paris]。(请参阅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)(这是Noda Time的默认值)

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

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

1
支持什么?你问题的这一部分不太清楚。嗯,我以为我在标题中已经写明了...但也说得过去——我已经更新了问题。如果你的意思是支持ISO-8601日期时间偏移+时区ID的字符串表示形式,有些平台支持,有些不支持。那么,我的问题就是其他平台在做什么?我希望有人能给我一些其他的例子,这样我就可以知道Java是否独自这样做,还是遵循了某种趋势。 - Garret Wilson
1
此外,听起来你要找的是RFC。也许你应该提出一个? :) - Matt Johnson-Pint
3
嘿,我刚刚发现ISO正在起草ISO8601-2“扩展”的草案,你可以联系他们建议将其包含在内。 :) - Matt Johnson-Pint
1
请注意 - 我在这里开始了一个Twitter话题[链接],如果您想要加入讨论的话。 :) - Matt Johnson-Pint
1
@GarretWilson - FYI - 现在有一个IETF的草案提议扩展RFC3339,其中包括用方括号标识时区等内容:https://github.com/ryzokuken/draft-ryzokuken-datetime-extended - Matt Johnson-Pint
显示剩余6条评论

26

马特·约翰逊的回答是非常正确的。我想再补充一些想法。

时区与UTC偏移量

UTC偏移量只是一个小时、分钟和秒数,表示比UTC快或慢多少时间。单独使用它不能准确地确定日期时间。因此,同时包含官方时区名称更为详细。

虽然目前还没有标准要求包含时区名称,但我希望其他人能够效仿java.time类,在方括号中添加时区名称。这种格式对我来说很合理,因为可以简单地截取方括号部分以向后兼容不精通软件。

例如:
2011-12-03T10:15:30+01:00[欧洲/巴黎]。如果数据只有2011-12-03T10:15:30+01:00,我们可以确定时间轴上的时刻,但无法将其他时刻调整到相同的帧中,因为我们不知道要应用哪些调整规则。诸如欧洲/萨格勒布非洲/布拉柴维尔北极/朗伊尔城欧洲/马恩岛等区域都共享+01:00的偏移量,但它们可能会有其他不同于欧洲/巴黎的调整。因此,如果你尝试将三天添加到值2011-12-03T10:15:30+01:00中,你实际上无法准确计算结果,因为你不知道在这三天内可能发生的DST换季等需要应用的调整。
一个时区定义了处理异常情况,如夏令时(DST)的一组规则。世界各地的政治家喜欢调整他们的时区,甚至重新定义它们。因此这些规则经常会变化。将时区视为随时间变化的偏移量集合,在历史上的许多时间段中,每个时间段在该特定区域中使用特定的偏移量。
您可以将时区视为偏移量-从UTC值的集合。在America/Los_Angeles的一部分今年比UTC晚8小时,而该年的另一部分将比UTC晚7小时。这使得作为该时区的一部分收集了2个数据点。
另一个例子是,在以前的几年里,土耳其每年的一部分比UTC快2小时,每年的另一部分比UTC快3小时。在2016年,这种情况改变为无限期地保持比UTC快3小时。因此,时区Europe/Istanbul中有多个数据点。

只需使用UTC

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

通常,存储和交换日期时间值时最好使用UTC。将UTC视为唯一真实的时间,带区域或偏移值仅是变体。


2
总体上同意使用UTC的建议,如果可能的话。然而,有些用例很棘手:如果逻辑必须引用过去或未来的任意事件,而唯一的时间信息在本地时区,则UTC转换并不明显。(例如,从现在起10年后的三月第二个星期二纽约证券交易所将在什么时间开市?在当地时间,最可能是东部时间上午9:30,但UTC取决于夏令时转换 - 甚至这也取决于规则在那之前是否更改。)因此,在这种情况下,最好有一个表示本地时区时间的标准。 - sumitsu
1
@Sumitsu 我完全同意,百分之百。我强调相反的立场是因为我发现程序员倾向于(a)让自己疯狂地转换他们自己教区的时区,以及(b)认为(祈祷?)使用“本地”(未分区)日期时间值将使他们免于处理时区问题。但正如你所说,“LocalDateTime”在许多情况下确实非常有用,特别是像纽约证券交易所开盘这样的约会,因为政客经常、粗心和迅速地重新定义时区。例如,就在去年,土耳其决定只提前几周保持夏令时。 - Basil Bourque
仅时区偏移量允许收集一些客户端相关值。虽然不像其他目的的TZ名称那样强大,但它确实提供了一个小步骤..主要是(在记录时间的99%情况下)允许“天”与时间分开捕获,同时在“单个标量”中捕获两者。 TZ偏移具有比TZ名称更好的属性,因为它是到UTC的纯映射,尽管能够以这种“单个标量”形式捕获TZ名称将有助于实现未来的改进处理:} - user2864740
在仅使用UTC时间的方法中,人们经常会忽略“一天”的纯粹概念。然而,在生活的许多方面,所有相关的只是这一天和相对时间。在这种普遍情况下,这一天是否在一年中向前或向后跳跃到“真实时间”并不重要。 - user2864740

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接