为什么ZoneOffset.UTC!= ZoneId.of(“UTC”)?

时间:2016-09-15 08:55:52

标签: java datetime java-8 java-time

为什么

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

打印出false

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

1 个答案:

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