java - manejo - ¿Por qué ZoneOffset.UTC!=ZoneId.of("UTC")?
restar fechas en java 8 (1)
La respuesta proviene del
javadoc de
ZoneId
(énfasis mío) ...
Se utiliza un ZoneId para identificar las reglas utilizadas para convertir entre un InstantDate y LocalDateTime. Hay dos tipos distintos de identificación:
- Desplazamientos fijos: un desplazamiento totalmente 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 desde UTC / Greenwich
La mayoría de las compensaciones fijas están representadas por ZoneOffset. Llamar a normalized () en cualquier ZoneId asegurará que una ID de compensación fija se representará como ZoneOffset.
... y del
javadoc de
ZoneId#of
(énfasis mío):
Este método analiza la ID que produce un ZoneId o ZoneOffset. Se devuelve un ZoneOffset si la 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 método de
equals
para la comparación,
verifica la equivalencia de los objetos
.
Debido a la diferencia descrita, el resultado de la evaluación es
false
.
Cuando se utiliza el método
normalized()
como se propone en la documentación, la comparación usando
equals
devolverá
true
, ya que
normalized()
devolverá el
ZoneOffset
correspondiente:
Normaliza la ID de zona horaria, devolviendo un ZoneOffset donde sea posible.
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
Como dice la documentación, si usa
"Z"
o
"+0"
como ID de entrada, devolverá
ZoneOffset
directamente y no es necesario llamar a
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 método
isEqual
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
Por que
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
imprimir
false
?
Esperaría que las dos instancias
ZonedDateTime
sean iguales.