为什么

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

打印错误?

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


当前回答

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

A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime. There are two distinct types of ID: Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times Geographical regions - an area where a specific set of rules for finding the offset from UTC/Greenwich apply Most fixed offsets are represented by ZoneOffset. Calling normalized() on any ZoneId will ensure that a fixed offset ID will be represented as a ZoneOffset.

... and from zoneid#的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方法进行比较时,您将检查对象等价性。由于所描述的差异,评估结果为假。

当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

其他回答

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

A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime. There are two distinct types of ID: Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times Geographical regions - an area where a specific set of rules for finding the offset from UTC/Greenwich apply Most fixed offsets are represented by ZoneOffset. Calling normalized() on any ZoneId will ensure that a fixed offset ID will be represented as a ZoneOffset.

... and from zoneid#的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方法进行比较时,您将检查对象等价性。由于所描述的差异,评估结果为假。

当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