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

为什么

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

打印出false

我期望两个zonedDateTimes是平等的。

答案来自ZoneId的javadoc …

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

  • 固定偏移 – 与UTC /格林威治完全分离的偏移,对所有当地date使用相同的偏移量
  • 地理区域 – 适用于findUTC / Greenwich偏移的特定规则的区域

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

…从ZoneId#of的javadoc ZoneId#of

此方法parsing生成ZoneId或ZoneOffset的ID。 如果ID为“Z”,或者以“+”或“ – ”开头,则返回ZoneOffset

参数id被指定为"UTC" ,因此它将返回一个带偏移量的ZoneId ,该偏移量也以stringforms呈现:

 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

当按照文档中的build议使用normalized()方法时,使用equals的比较将返回true ,因为normalized()将返回相应的ZoneOffset

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

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

如文档所述,如果使用"Z""+0"作为inputID, ZoneOffset直接返回ZoneOffset ,并且不需要调用normalized()

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

要检查它们是否存储相同的date时间 ,可以使用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 

如果你把它们都放在String中,你会发现第一个是2016-09-15T09:01:13.816Z ,第二个是2016-09-15T09:01:13.816Z [UTC]它们实际上是一样的与zoneID你得到一个额外的[UTC]

编辑:检查@DVarga的答案,以便以你想要的方式得到它