为什么时区模式 "OOOO" 不显示完整的 GMT+00:00 偏移量格式?

Why does the timezone pattern "OOOO" not show the full GMT+00:00 offset format?

这是错误还是功能?

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

Four letters outputs the full form, which is localized offset text, such as 'GMT, with 2-digit hour and minute field, optional second field if non-zero, and colon, for example '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

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

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

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

您可以考虑提交 Oracle and/or OpenJDK 的错误(这些天我不确定正确的位置)。他们是否会拒绝它,修复文档或修复代码——我不敢尝试猜测。

解决方法:'GMT'xxx

Anyway, I want my +00:00 somehow.

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

Wed 2019.02.27 08:46:43.226 GMT+00:00

这不是错误。

Java 规范遵循 LDML (CLDR)。有关“本地化 GMT 格式”的定义,请参阅 here for the definition of "OOOO" and here

Localized GMT format: A constant, specific offset from GMT (or UTC), which may be in a translated form. There are two styles for this. The first is used when there is an explicit non-zero offset from GMT; this style is specified by the element and element. The long format always uses 2-digit hours field and minutes field, with optional 2-digit seconds field. The short format is intended for the shortest representation and uses hour fields without leading zero, with optional 2-digit minutes and seconds fields. The digits used for hours, minutes and seconds fields in this format are the locale's default decimal digits:

"GMT+03:30" (long)

"GMT+3:30" (short)

"UTC-03.00" (long)

"UTC-3" (short)

"Гриинуич+03:30" (long)

Otherwise (when the offset from GMT is zero, referring to GMT itself) the style specified by the element is used:

"GMT"

"UTC"

"Гриинуич"

由于与 GMT 的偏移量为零,因此适用底部子句,并且输出只是“GMT”(或任何适合您所在区域的本地化文本)。

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