为什么
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
打印出false
?
我希望两个ZonedDateTime
个实例相等。
答案 0 :(得分:123)
答案来自javadoc of ZoneId
(强调我的)......
ZoneId用于标识用于在a之间进行转换的规则 即时和LocalDateTime。有两种不同类型的ID:
- 固定偏移 - 与UTC / Greenwich完全解析的偏移量,对所有本地日期时间使用相同的偏移量
- 地理区域 - 用于查找从UTC /格林威治的偏移量的特定规则集适用的区域
大多数固定偏移量由ZoneOffset表示。 调用规范化() 在任何ZoneId上将确保将表示固定的偏移ID 作为ZoneOffset。
......来自javadoc of ZoneId#of
(强调我的):
此方法解析生成ZoneId或ZoneOffset的ID。 :一种 如果ID为' Z'或以' +'开头,则返回ZoneOffset。或' - ' 。
参数id指定为"UTC"
,因此它将返回带有偏移量的ZoneId
,该偏移量也以字符串形式显示:
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));
输出:
2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]
当您使用equals
方法进行比较时,检查对象等效性。由于描述的差异,评估结果为false
。
如文档中建议的那样使用normalized()
方法时,使用equals
的比较将返回true
,因为normalized()
将返回相应的ZoneOffset
:
规范化时区ID,尽可能返回ZoneOffset。
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
正如文档所述,如果您使用"Z"
或"+0"
作为输入ID,of
将直接返回ZoneOffset
,则无需调用{{1} }}:
normalized()
要检查是否存储相同的日期时间,您可以使用isEqual
方法代替:
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true
<强>示例强>
now.withZoneSameInstant(ZoneOffset.UTC)
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true
输出:
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"))));