La respuesta viene del javadoc deZoneId
(énfasis mío) ...
Un ZoneId se usa para identificar las reglas que se usan para convertir entre Instant y LocalDateTime. Hay dos tipos distintos de identificación:
- Desplazamientos fijos: un desplazamiento completamente resuelto de UTC / Greenwich, que utiliza el mismo desplazamiento para todas las fechas y horas locales
- Regiones geográficas: un área donde se aplica un conjunto específico de reglas para encontrar el desplazamiento de UTC / Greenwich
La mayoría de las compensaciones fijas están representadas por ZoneOffset. Llamar a normalized () en cualquier ZoneId garantizará que un ID de desplazamiento fijo se represente como ZoneOffset.
... y del javadoc deZoneId#of
(énfasis mío):
Este método analiza el ID que produce un ZoneId o ZoneOffset. Se devuelve un ZoneOffset si el ID es 'Z' o comienza con '+' o '-' .
El id del argumento se especifica como "UTC"
, por lo tanto, devolverá un ZoneId
con un desplazamiento, que también se presenta en forma de cadena:
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));
Salidas:
2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]
A medida que utiliza el equals
método de comparación, comprueba la equivalencia de objetos . Debido a la diferencia descrita, el resultado de la evaluación es false
.
Cuando normalized()
se utilice el método propuesto en la documentación, equals
se devolverá la comparación utilizando true
, ya normalized()
que devolverá el correspondiente ZoneOffset
:
Normaliza el ID de la zona horaria, devolviendo un ZoneOffset siempre que sea posible.
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
Como indica la documentación, si usa "Z"
o "+0"
como ID de entrada, of
devolverá el ZoneOffset
directamente y no es necesario llamar normalized()
:
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true
Para verificar si almacenan la misma fecha y hora , puede usar el isEqual
método en su lugar:
now.withZoneSameInstant(ZoneOffset.UTC)
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true
Muestra
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"))));
Salida:
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.of("Z")
te daZoneOffset.UTC
pero teZoneId.of("UTC")
da unZoneId
(que no esZoneOffset.UTC
). Esta API no es intuitiva, por decir lo menos.