ZoneOffset.UTC 和 ZoneId.of(“UTC”) 有什么区别?

2022-08-31 06:28:43

为什么

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

打印出来 ?false

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


答案 1

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

ZoneId 用于标识用于在即时和 LocalDateTime 之间进行转换的规则。有两种不同类型的 ID:

  • 固定偏移量 - 来自 UTC/格林威治的完全解析偏移量,对所有本地日期时间使用相同的偏移量
  • 地理区域 - 应用一组特定规则来查找与 UTC/格林威治的偏移量的区域

大多数固定偏移由区域偏移表示。在任何 ZoneId 上调用 normalized() 将确保固定偏移 ID 将表示为 ZoneOffset。

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

此方法分析生成 ZoneId 或 ZoneOffset 的 ID。如果 ID 为“Z”或以“+”或“-”开头,则返回区域偏移

参数 id 指定为 ,因此它将返回带有偏移量的 a,该偏移量也以字符串形式显示:"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]

使用比较方法时,请检查对象等效性。由于所描述的差异,评估的结果是 。equalsfalse

当按照文档中的建议使用规范化()方法时,将使用的比较将返回 ,将返回相应的:equalstruenormalized()ZoneOffset

规范化时区 ID,并在可能的情况下返回区域偏移。

now.withZoneSameInstant(ZoneOffset.UTC)
    .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true

如文档所述,如果您使用 或 作为输入 ID,将直接返回 ,无需调用 :"Z""+0"ofZoneOffsetnormalized()

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

答案 2