なぜZoneOffset.UTC!= ZoneId.of(“ UTC”)なのですか?


125

どして

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

印刷するfalse

私は両方のZonedDateTimeインスタンスが等しいことを期待します。

回答:


180

答えは(強調鉱山)のjavadocZoneIdから来ています...

ZoneIdは、InstantとLocalDateTime間の変換に使用されるルールを識別するために使用されます。IDには2つの異なるタイプがあります。

  • 固定オフセット-すべてのローカル日時に同じオフセットを使用する、UTC /グリニッジからの完全に解決されたオフセット
  • 地理的領域-UTC /グリニッジからのオフセットを見つけるための特定のルールセットが適用される領域

ほとんどの固定オフセットはZoneOffsetで表されます。任意のZoneIdでNormalized()を呼び出すと、固定オフセットIDが確​​実にZoneOffsetとして表されます。

...そして(私の鉱山)のjavadocZoneId#ofから:

このメソッドは、ZoneIdまたはZoneOffsetを生成するIDを解析します。IDが「Z」の場合、または「+」または「-」で始まる場合、ZoneOffsetが返されます。

引数idはとして指定されている"UTC"ためZoneId、オフセットとともにa を返します。これも文字列形式で表示されます。

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()ドキュメントで提案されているようにメソッドが使用される場合、を使用した比較equalstrueたように、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

4
ドキュメントはまた、「ゾーンIDが「GMT」、「UTC」、または「UT」と等しい場合、結果は同じIDを持つZoneIdであり、ZoneOffset.UTCと同等のルールです」と述べています。IDとルールは同じですが、動作が異なります。ZoneId.of("Z")あなたを与えるZoneOffset.UTCが、ZoneId.of("UTC")あなたなりますZoneId(つまりではありませんZoneOffset.UTC)。このAPIは控えめに言っても直感的ではありません。
アダムMillerchip
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.