Saltar al contenido

Cómo convertir LocalDateTime a Date en Java 8

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, CalendarY 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.

LocalDateTime

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *