web-dev-qa-db-fra.com

Pourquoi ZoneOffset.UTC! = ZoneId.of ("UTC")?

Pourquoi

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

imprimer false?

Je m'attendrais à ce que les deux instances ZonedDateTime soient égales.

95
Johannes Flügel

La réponse vient du javadoc de ZoneId (souligné par moi) ...

Un ZoneId est utilisé pour identifier les règles utilisées pour convertir entre un Instant et un LocalDateTime. Il existe deux types d'identifiant distincts:

  • Décalages fixes - décalage totalement résolu par rapport à UTC/Greenwich, qui utilise le même décalage pour toutes les heures locales.
  • Régions géographiques - une zone dans laquelle un ensemble spécifique de règles permettant de déterminer le décalage entre UTC et Greenwich s’applique

La plupart des décalages fixes sont représentés par ZoneOffset. L'appel normalisé () sur n'importe quel ZoneId garantira qu'un identifiant de décalage fixe sera représenté par un ZoneOffset.

... et du javadoc de ZoneId#of (souligné par moi):

Cette méthode analyse l'ID produisant un ZoneId ou un ZoneOffset. Un ZoneOffset est renvoyé si l'ID est 'Z' ou commence par '+' ou '-' .

L'argument id est spécifié sous la forme "UTC". Par conséquent, il renverra un ZoneId avec un décalage, également présenté sous la forme de chaîne:

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

Sorties:

2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]

Lorsque vous utilisez la méthode equals à des fins de comparaison, vous vérifiez l'équivalence des objets . En raison de la différence décrite, le résultat de l'évaluation est false.

Lorsque la méthode normalized() est utilisée comme proposé dans la documentation, la comparaison à l'aide de equals renverra true, car normalized() renverra le ZoneOffset correspondant:

Normalise l'ID de fuseau horaire, renvoyant un ZoneOffset si possible.

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

Comme indiqué dans la documentation, si vous utilisez "Z" ou "+0" comme ID d'entrée, of renverra directement le ZoneOffset et il n'est pas nécessaire d'appeler normalized():

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

Pour vérifier s’ils stockent la même heure , vous pouvez utiliser la méthode isEqual :

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

Échantillon

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

Sortie:

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
138
DVarga