Esta es la contestación más acertada que te podemos compartir, sin embargo obsérvala detenidamente y valora si se puede adaptar a tu proyecto.
Solución:
LocalDateTime
significa que no hay zona
Parece malinterpretar el propósito de LocalDateTime
.
Esta clase no tiene zona horaria ni desplazamiento de UTC. Está no un punto en la línea de tiempo. Más bien representa una idea vaga sobre posibles momentos. El nombre “Local …” puede ser contrario a la intuición. no representan cualquier localidad en particular, sino más bien alguna localidad.
Por ejemplo, la Navidad de este año es la medianoche a principios del 25 de diciembre de 2016, o 2016-12-25T00:00
. Esto no tiene sentido hasta que aplica una zona horaria para obtener Navidad en Auckland NZ o Kolkata IN o Paris FR o Montréal CA, cada uno es un punto diferente en la línea de tiempo, cada vez más tarde a medida que avanza hacia el oeste.
Nunca usar LocalDateTime
porque cree que le ahorrará la molestia de zonas y compensaciones. Todo lo contrario, te estarás cavando en un agujero con valores ambiguos de fecha y hora.
Centrarse en UTC
La mayor parte de la lógica empresarial, el registro, el almacenamiento de datos y el intercambio de datos deben estar en UTC. Piense en UTC como el true tiempo; todas las demás zonas y compensaciones se disfrazan de valores UTC disfrazados.
En java.time, eso significa que Instant
class es su clase de referencia, los componentes básicos de los objetos de fecha y hora. los Instant
La clase representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos.
Instant now = Instant.now();
ZonedDateTime
Ajústelo a las zonas horarias solo cuando sea necesario para acceder a la hora del reloj de pared de alguna región. Aplicar una ZoneId
conseguir un ZonedDateTime
objeto.
ZoneId zNewYork = ZoneId.of("America/New_York");
ZoneId zRecife = ZoneId.of("America/Recife");
ZonedDateTime zdtNewYork = now.atZone( zNewYork );
ZonedDateTime zdtRecife = now.atZone( zRecife );
Los tres de estos objetos, now
, zdtNewYork
, y zdtRecife
, están todo el muy algún momento, el mismo punto simultáneo en la línea de tiempo. Los tres comparten el mismo recuento de época. La única diferencia es la lente a través de la cual vemos la hora de su reloj de pared.
Evite las clases de fecha y hora heredadas
Evite el uso de las problemáticas clases de fecha y hora antiguas incluidas con las primeras versiones de Java. Entonces, evita java.util.Date
y java.util.Calendar
. Realmente son tan malos. Quédate con las clases de java.time.
Si debe interactuar con código antiguo aún no actualizado para tipos java.time, puede convertir a / desde tipos java.time. Busque nuevos métodos agregados a las clases antiguas. los java.util.Date.from
el método toma un Instant
. Podemos extraer un Instant
a partir de una ZoneDateTime
(o de OffsetDateTime
).
java.util.Date utilDate = java.util.Date.from( zdtNewYork.toInstant() );
Y yendo en la otra dirección.
Instant instant = utilDate.toInstant();
Para obtener más información sobre la conversión, consulte mi Respuesta a la pregunta, ¿Convertir java.util.Date a qué tipo “java.time”?
Evite contar desde una época
Evite el uso de números de recuento desde la época, como milisegundos desde el inicio de 1970 en UTC. Hay varias granularidades utilizadas para el recuento (milisegundos, microsegundos, nanosegundos, segundos enteros y más). Hay al menos un par de docenas de épocas en uso por varios sistemas informáticos además de 1970. Los números no tienen significado cuando los leen los humanos, por lo que los errores pueden pasar desapercibidos.
Puede que le resulten útiles a la hora de practicar. Llama getEpochSecond
y getNano
sobre Instant
, o para una llamada de valor truncada toEpochMilli
.
Sobre java.time
los java.time framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan las antiguas y problemáticas clases de fecha y hora heredadas, como java.util.Date
, Calendar
Y SimpleDateFormat
.
los Joda-Time proyecto, ahora en modo de mantenimiento, aconseja la migración a las clases java.time.
Para obtener más información, consulte el Tutorial de Oracle. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310.
Puedes intercambiar java.time objetos directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. Sin necesidad de cuerdas, sin necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11y posterior: parte de la API estándar de Java con una implementación integrada.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de java.time está retroportada a Java 6 y 7 en ThreeTen-Backport.
- Androide
- Versiones posteriores de implementaciones de paquetes de Android del java.time clases.
- Para Android anterior (<26), el ThreeTenABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo usar ThreeTenABP….
los ThreeTen-Extra el proyecto extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
, y más.
Me parece que estás confundido acerca de la diferencia entre un LocalDateTime
y un Instant
(o un Date
, que es esencialmente lo mismo que un Instant
). Estos son objetos completamente diferentes.
A LocalDateTime
es una fecha de calendario particular y una hora de reloj particular. Puedes pensar en ello como en esta imagen.
O puede pensar en ello como un año, mes, día, hora, minuto y segundo. Pero no tiene zona horaria. Es solo lo que dice el calendario y lo que dice el reloj.
Un Instant
es un momento en el tiempo. Por ejemplo, el momento en que Neil Armstrong pisó la luna por primera vez podría representarse como un Instant
. Lo mismo ocurrió con el momento en que dispararon a JFK.
Nuevamente, no hay zona horaria. Pero es algo diferente de un LocalDateTime
. No puedes escribir a qué hora y Instant
es a menos que sepa en qué zona horaria debe anotarlo. Oh, y un Date
es lo mismo que un Instant
.
Por lo tanto, para convertir entre un LocalDateTime
y un Instant
, debe hacer referencia a una zona horaria en particular. Entonces, para expresar el momento en que Neil Armstrong pisó la luna como año, mes, fecha, hora, minuto y segundo; necesita saber qué zona horaria utilizar. Si usa UTC, fueron las 2:56 am del 21 de julio de 1969. Si usa la hora estándar del Pacífico, fueron las 6:56 pm del 20 de julio de 1969.
Armados con ese conocimiento, analicemos su código. Empezaste con un par de LocalDateTime
objetos.
- ldtBrazil es la hora actual en Brasil – 22:11:52 del 21 de septiembre.
- ldtNY es la hora actual en Nueva York: 21:11:52 del 21 de septiembre.
Ahora, usa UTC para convertirlos a Instant
objetos.
- instantBrazil es el momento en el que eran las 22:11:52 en Tombuctú (que usa UTC durante todo el año).
- instantNY es el momento en el que eran las 21:11:52 en Tombuctú (una hora antes que instantBrazil).
Luego imprime estos. Necesitamos saber una zona horaria para poder hacer esto, pero está bien. Un Instant
se imprime en UTC, pase lo que pase. Eso es lo que el Z
medio.
Ahora, convierte el Instant
objetos a varios milisegundos. Multa. Este es el número de milisegundos desde la medianoche del 1 de enero de 1970, UTC. milliNY es obviamente 3,6 millones menos que milliBrazil, porque corresponde a un Instant
eso es una hora antes.
Luego conviertes el Instant
objetos a Date
objetos. Esto realmente no cambia nada, ya que un Date
y un Instant
representan lo mismo, aunque se impriman de forma diferente.
Imprime los convertidos Date
objetos. Se imprimen en hora brasileña, porque ese es su lugar. Y da la casualidad de que dateNY
es una hora antes que dateBrazil
; pero ambos se imprimen en la hora brasileña, que está tres horas por detrás de UTC. Entonces obtienes 19:11:52 y 18:11:52 respectivamente.
Por último, haces un par de más Date
objetos, desde el número de milisegundos. Pero estos nuevos Date
los objetos son exactamente iguales a los dateBrazil
y dateNY
que ya tienes, ya que los hiciste a partir de la misma cantidad de milisegundos. Y nuevamente, se imprimen en tiempo brasileño.
Te mostramos comentarios y puntuaciones
Te invitamos a añadir valor a nuestro contenido aportando tu experiencia en las críticas.