【问题标题】:Why does the timezone pattern "OOOO" not show the full GMT+00:00 offset format?为什么时区模式“OOOO”不显示完整的 GMT+00:00 偏移格式?
【发布时间】:2019-02-25 22:58:20
【问题描述】:

这是错误还是功能?

DateTimeFormatter JavaDoc 明确指出,当我在格式化程序中使用 OOOO 模式时,应使用本地化时区的完整形式(强调我的):

四个字母输出完整形式,即本地化的偏移文本,例如'GMT,带有2位小时和分钟字段,如果非零则可选第二个字段,冒号,例如'GMT+08:00'。

但如果时间是 GMT+0:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE yyyy.MM.dd HH:mm:ss.SSS OOOO");

String timestamp = OffsetDateTime.ofInstant(Instant.now(), ZoneOffset.UTC).format(formatter);
System.out.println(timestamp);

这是输出:

Mon 2019.02.25 22:30:00.586 GMT

预期:

Mon 2019.02.25 22:30:00.586 GMT+00:00

【问题讨论】:

  • 它并不完全直接,但 Z 说明符说“如果偏移量为零,输出将是相应的本地化偏移量文本”。如果这会导致GMT+0000,那将是奇怪的,因为那将只是具有非零偏移量的Z;换句话说,没有必要把它当作特例。
  • 对 javadoc 的严格阅读表明,至少对我而言,OOOO 只能保证生成“完整的形式,即本地化的偏移文本”。给出的示例是“GMT,具有两位数的小时和分钟字段,可选的第二个字段(如果非零)和冒号”,但我不认为它是保证 完整的表格包括一个冒号或小时/分钟。可以说祖鲁时间没有偏移。
  • 我在 Java 8、10 和 11 上进行了复制。观察到的行为也不符合我阅读文档的方式。如果偏移量不是 0,我会得到预期的值,例如 GMT+02:00
  • @OleV.V.如果任何其他方法也包含相同的检查,则它可能是由于昏昏欲睡的复制粘贴导致的,因此是一个错误。无论如何,我想要我的 +00:00。
  • @VGR 它明确指出第二个字段是可选的,它不是小时和分钟,这将使它们成为非可选的 IMO。

标签: java datetime datetime-format timezone-offset java-time


【解决方案1】:

一个错误?我们似乎同意观察到的行为与文档不一致(或者至少您必须对文档进行非常有创意的阅读才能使其匹配)。

功能?据我所知,观察到的行为在某个时候是有意识的决定。 DateTimeFormatterBuilder 内的私有内部类LocalizedOffsetIdPrinterParser 的源代码在打印小时、分钟和秒之前包含if (totalSecs != 0) {。它看起来不像是复制粘贴错误,因为完全相同的代码行在文件中没有其他地方(偏移量 0 在许多地方被特殊处理,但我不知道其他地方它被完全遗漏了)。

在 Java 8 格式模式 OOOO 上既不能单独解析 GMT 也不能解析 GMT+00:00,这一定是一个错误。它在 Java 11 中已修复。在 Java 11 上,OOOO 单独解析 GMT 就可以了,所以他们一定认为这是可以接受的(不过,它也解析了 GMT+00:00GMT-00:00)。

您可以考虑向 Oracle 和/或 OpenJDK 提交错误(这些天我不确定合适的地方)。他们是否会拒绝它,修复文档或修复代码 - 我不敢猜测。

解决方法:'GMT'xxx

无论如何,我想要我的 +00:00。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE yyyy.MM.dd HH:mm:ss.SSS 'GMT'xxx");

2019 年 2 月 27 日星期三 08:46:43.226 GMT+00:00

【讨论】:

  • 是的!感谢您的解决方法。就我而言,我将使用'GMT'xxxxx 时区模式,它也非常有效:Wed 2019.02.27 15:32:59.347 GMT+00:00
  • 由于“错误”在 Oracle 文档中,我已将其报告给他们。让我们看看会发生什么..
【解决方案2】:

这不是错误。

Java 规范遵循 LDML (CLDR)。 “OOOO”的定义见here,“本地化GMT格式”的定义见here

本地化 GMT 格式:相对于 GMT(或 UTC)的常量、特定偏移量,可以是翻译形式。有两种风格。当与 GMT 存在显式非零偏移时,使用第一个;此样式由元素和元素指定。长格式始终使用 2 位数的小时字段和分钟字段,以及可选的 2 位数秒字段。短格式旨在用于最短表示,并使用不带前导零的小时字段,以及可选的 2 位数分钟和秒字段。此格式中用于小时、分钟和秒字段的数字是语言环境的默认十进制数字:

“GMT+03:30”(长)

“GMT+3:30”(短)

“UTC-03.00”(长)

“UTC-3”(短)

“Гриинуич+03:30”(长)

否则(当与 GMT 的偏移量为零时,指的是 GMT 本身)使用元素指定的样式:

“格林威治标准时间”

“世界标准时间”

"Гриинуич"

由于与 GMT 的偏移量为零,因此底部子句适用,并且输出只是“GMT”(或任何适合您的语言环境的正确本地化文本)。

希望 Javadoc 可以在未来的版本中得到澄清。

【讨论】:

    猜你喜欢
    • 2019-09-02
    • 2016-04-28
    • 2017-08-08
    • 2012-08-08
    • 2011-06-27
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多