ZoneOffset之间的区别是什么。UTC和ZoneId.of("UTC")?

为什么

ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));

打印出false?

我希望两个ZonedDateTime实例是相等的。

189919 次浏览

答案来自ZoneId的javadoc(强调我的)…

ZoneId用于标识用于在和 Instant和LocalDateTime。有两种不同类型的ID:

  • 固定偏移量——从UTC/Greenwich完全解析的偏移量,对所有本地日期时间使用相同的偏移量
  • 地理区域——应用一组特定规则查找UTC/格林威治偏移量的区域
大多数固定偏移量由ZoneOffset表示。<强>调用规范化() 将确保一个固定的偏移量ID将被表示 作为一个ZoneOffset.

.

... 和来自ZoneId#of的javadoc(强调我的):

这个方法解析产生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,不需要调用normalized():

now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true

要检查如果它们存储相同的日期时间,可以使用isEqual方法:

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"))));

输出:

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