在ISO 8601中识别时区

Gar*_*son 18 java timezone iso8601 timezone-offset

不,我不是在谈论区域偏移 - 这些区域在一年中可能因基于例如夏令时的区域而变化.我在谈论IANA维护的实际时区.我理解ISO 8601 支持这些,对吗?

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

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

Mat*_*int 18

我理解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) (这是Noda Time的默认值)

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

{
  "timestamp": "2011-12-03T10:15:30+01:00",
  "timezone": "Europe/Paris"
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,我刚刚发现[在ISO的作品中有ISO8601-2"扩展"草案](https://www.iso.org/news/2017/02/Ref2164.html),当然我马上想到了你.也许你可以联系他们建议包括这个?:) (3认同)

Bas*_*que 11

Matt Johnson回答是正确的.我只想补充几点想法.

时区与UTC的偏移量

一个偏移从-UTC仅仅是若干小时,分钟和秒超前/落后UTC.单独,这确实将日期时间变为时间轴上的特定时刻.但它并不像包括官方时区名称那样提供信息.

虽然还没有包含时区名称的标准,但我希望其他人跟随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切换.

时区定义用于处理诸如夏令时(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 转换 - 即使这也取决于规则在此之前不会改变。)因此在这种情况下,最好有一个代表本地分区时间的标准。 (2认同)