在 ISO 8601 中识别时区时区与 UTC 偏移量只需使用UTC

2022-09-01 01:33:34

不,我不是在谈论区域偏移量---这些偏移量在一年中可能会根据例如DST而变化。我说的是IANA维护的实际时区。我知道ISO 8601不支持这些,对吗?

平台正在采取哪些措施来支持在类似 ISO 8601 的字符串表示形式中标识时区?我注意到最新的Java日期/时间库正在为此使用扩展的ISO 8601格式,例如.(请参阅 DateTimeFormatter API2011-12-03T10:15:30+01:00[Europe/Paris]

是否有一些融合约定(例如,与其他语言和平台)来扩展ISO 8601以支持时区指定?


答案 1

更新:

现在有一个IETF提案草案,将RFC3339与时区标识符放在方括号中扩展,其中包括:https://datatracker.ietf.org/doc/draft-ietf-sedate-datetime-extended/

原始答案:

我知道ISO 8601不支持这些,对吗?

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

平台正在做些什么来支持这一点?

究竟支持什么?您问题的这一部分尚不清楚。如果您打算支持 IANA 时区,那么这里无处不在。有些平台内置了它们,有些平台依赖于库。如果您打算支持 ISO-8601 日期-时间偏移量 + 时区 ID 的字符串表示形式,则某些平台具有此 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)(这是野田时间的默认设置)

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

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

答案 2

马特·约翰逊(Matt Johnson)的答案是正确的。我只想补充一些想法。

时区与 UTC 偏移量

与 UTC 的偏移量只是 UTC 之前/之后的小时数、分钟数和秒数。仅此一项,这确实使日期时间成为时间轴上的特定时刻。但它并不像包括官方时区名称那样具有信息量。

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

例如:
.如果数据只是 ,我们将能够识别时间轴上的时刻,但无法将其他时刻调整到相同的思维框架中,因为我们不知道要应用什么调整规则。诸如 、 、 和 等区域都共享 的偏移量,但它们很可能具有与 的调整不同的其他有效调整。因此,如果您尝试向值添加三天,则确实无法忠实地计算结果,因为您不知道可能需要应用哪些调整,例如在这三天内可能发生的DST转换。2011-12-03T10:15:30+01:00[Europe/Paris]2011-12-03T10:15:30+01:00Europe/ZagrebAfrica/BrazzavilleArctic/LongyearbyenEurope/Isle_of_Man+01:00Europe/Paris2011-12-03T10:15:30+01:00

时区定义用于处理异常(如夏令时 (DST))的规则集。世界各地的政治家都喜欢调整他们的时区,甚至重新定义它们。所以这些规则经常变化。将时区视为随时间变化的偏移量的集合,在历史上的许多时间段中,每个时间段在该特定区域使用的特定偏移量。

您可以将时区视为与 UTC 的偏移量值的集合。在美国/Los_Angeles今年的部分时间比UTC晚8小时,而一年的一部分时间将比UTC晚7个小时。这使得作为该时区的一部分收集的2点数据。

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

只需使用UTC

就个人而言,我认为即使使用诸如.如果没有时区,您也可以单独使用UTC。在本例中为(上午 9 点而不是上午 10 点)。2011-12-03T10:15:30+01:002011-12-03T09:15:30Z

通常,最佳做法是在存储和交换日期时间值时使用 UTC。将 UTC 视为一个真实时间,其中分区值或偏移值只是变化。


推荐