Java 为什么是 ZoneOffset.UTC != ZoneId.of("UTC")?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39506891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is ZoneOffset.UTC != ZoneId.of("UTC")?
提问by Johannes Flügel
Why does
为什么
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
print out false
?
打印出来false
?
I would expect the both ZonedDateTime
instances to be equal.
我希望这两个ZonedDateTime
实例是平等的。
采纳答案by DVarga
The answer comes from the javadoc of ZoneId
(emphasis mine) ...
答案来自(强调我的)的javadocZoneId
...
A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime. There are two distinct types of ID:
- Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times
- Geographical regions - an area where a specific set of rules for finding the offset from UTC/Greenwich apply
Most fixed offsets are represented by ZoneOffset. Calling normalized() on any ZoneId will ensure that a fixed offset ID will be represented as a ZoneOffset.
ZoneId 用于标识用于在 Instant 和 LocalDateTime 之间转换的规则。有两种不同类型的 ID:
- 固定偏移量 - UTC/格林威治的完全解析偏移量,对所有本地日期时间使用相同的偏移量
- 地理区域 - 应用一组特定规则来查找 UTC/格林威治偏移量的区域
大多数固定偏移量由 ZoneOffset 表示。对任何 ZoneId 调用 normalized() 将确保固定偏移 ID 将表示为 ZoneOffset。
... and from the javadoc of ZoneId#of
(emphasis mine):
...以及来自(强调我的)的javadocZoneId#of
:
This method parses the ID producing a ZoneId or ZoneOffset. A ZoneOffset is returned if the ID is 'Z', or starts with '+' or '-'.
此方法解析 ID 生成 ZoneId 或 ZoneOffset。如果 ID 为 'Z',或者以 '+' 或 '-' 开头,则返回 ZoneOffset。
The argument id is specified as "UTC"
, therefore it will return a ZoneId
with an offset, which also presented in the string form:
参数 id 被指定为"UTC"
,因此它将返回ZoneId
带有偏移量的 a ,它也以字符串形式呈现:
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));
Outputs:
输出:
2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]
As you use the equals
method for comparison, you check for object equivalence. Because of the described difference, the result of the evaluation is false
.
当您使用该equals
方法进行比较时,您会检查对象等效性。由于所描述的差异,评估结果为false
。
When the normalized()
method is used as proposed in the documentation, the comparison using equals
will return true
, as normalized()
will return the corresponding ZoneOffset
:
当按照normalized()
文档中的建议使用该方法时,比较 usingequals
将返回true
,normalized()
并将返回相应的ZoneOffset
:
Normalizes the time-zone ID, returning a ZoneOffset where possible.
标准化时区 ID,在可能的情况下返回 ZoneOffset。
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
As the documentation states, if you use "Z"
or "+0"
as input id, of
will return the ZoneOffset
directly and there is no need to call normalized()
:
正如文档所述,如果您使用"Z"
或"+0"
作为输入 id,of
将ZoneOffset
直接返回 ,无需调用normalized()
:
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true
To check if they store the same date time, you can use the isEqual
method instead:
要检查它们是否存储相同的日期时间,您可以改用该isEqual
方法:
now.withZoneSameInstant(ZoneOffset.UTC)
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true
Sample
样本
System.out.println("equals - ZoneId.of(\"UTC\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
System.out.println("equals - ZoneId.of(\"UTC\").normalized(): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())));
System.out.println("equals - ZoneId.of(\"Z\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("Z"))));
System.out.println("equals - ZoneId.of(\"+0\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("+0"))));
System.out.println("isEqual - ZoneId.of(\"UTC\"): "+ nowZoneOffset
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))));
Output:
输出:
equals - ZoneId.of("UTC"): false
equals - ZoneId.of("UTC").normalized(): true
equals - ZoneId.of("Z"): true
equals - ZoneId.of("+0"): true
isEqual - ZoneId.of("UTC"): true