Java 8 tiene una API completamente nueva para fecha y hora. Una de las clases más útiles en esta API es LocalDateTime, para mantener un valor de fecha con hora independiente de la zona horaria.
Probablemente hay millones de líneas de código que usan la clase heredada java.util.Datepara este propósito. Como tal, cuando se interconecta el código antiguo y el nuevo, será necesario convertir entre los dos. Como parece que no hay métodos directos para lograr esto, ¿cómo se puede hacer?

Respuestas:
Respuesta corta:
Explicación: (basado en esta pregunta sobre
LocalDate)A pesar de su nombre,
java.util.Daterepresenta un instante en la línea de tiempo, no una "fecha". Los datos reales almacenados dentro del objeto son unlongrecuento de milisegundos desde 1970-01-01T00: 00Z (medianoche al comienzo de 1970 GMT / UTC).La clase equivalente a
java.util.Dateen JSR-310 esInstant, por lo tanto, hay métodos convenientes para proporcionar la conversión de aquí para allá:Una
java.util.Dateinstancia no tiene concepto de zona horaria. Esto puede parecer extraño si llamatoString()a unjava.util.Date, porquetoStringes relativo a una zona horaria. Sin embargo, ese método en realidad usa la zona horaria predeterminada de Java sobre la marcha para proporcionar la cadena. La zona horaria no es parte del estado real dejava.util.Date.An
Instanttampoco contiene ninguna información sobre la zona horaria. Por lo tanto, para convertirInstantuna fecha y hora local en una hora local, es necesario especificar una zona horaria. Esta podría ser la zona predeterminadaZoneId.systemDefault(), o podría ser una zona horaria que controla su aplicación, como una zona horaria de las preferencias del usuario.LocalDateTimetiene un método de fábrica conveniente que toma tanto el instante como la zona horaria:A la inversa, la
LocalDateTimezona horaria se especifica llamando alatZone(ZoneId)método. LaZonedDateTimecontinuación, se puede convertir directamente a unInstant:Tenga en cuenta que la conversión de
LocalDateTimeaZonedDateTimetiene el potencial de introducir un comportamiento inesperado. Esto se debe a que no todas las fechas y horas locales existen debido al horario de verano. En otoño / otoño, hay una superposición en la línea de tiempo local donde la misma fecha y hora local ocurre dos veces. En primavera, hay una brecha, donde desaparece una hora. Consulte el Javadoc deatZone(ZoneId)para obtener más información sobre lo que hará la conversión.Resumen, si una de ida y vuelta
java.util.Datea unaLocalDateTimey de nuevo a unajava.util.Dateque puede terminar con una instantánea diferente debido al horario de verano.Información adicional: hay otra diferencia que afectará las fechas muy antiguas.
java.util.Dateusa un calendario que cambia el 15 de octubre de 1582, con fechas anteriores al calendario juliano en lugar del gregoriano. Por el contrario,java.time.*utiliza el sistema de calendario ISO (equivalente al gregoriano) de todos los tiempos. En la mayoría de los casos de uso, el sistema de calendario ISO es lo que desea, pero puede ver efectos extraños al comparar fechas anteriores al año 1582.fuente
java.util.Dateno contiene zona horaria, pero imprímala durantetoString(). La documentación oficial del evento no dice esto claramente cuando publicas.LocalDateTime.ofInstant(date.toInstant()...no se comporta como uno esperaría ingenuamente. Por ejemplo,new Date(1111-1900,11-1,11,0,0,0);se convertirá en1111-11-17 23:53:28utilizar este enfoque. Eche un vistazo a la implementación dejava.sql.Timestamp#toLocalDateTime()si necesita que el resultado esté1111-11-11 00:00:00en el ejemplo anterior.java.sql.Date#toInstantarroja unUnsupportedOperationException. Así que no lo usestoInstanten un RowMapperjava.sql.ResultSet#getDate.Esto es lo que se me ocurrió (y, como todos los acertijos de fecha y hora, probablemente será refutado en función de algún ajuste extraño de la zona horaria, el día de verano y el día: D)
Disparo redondo:
Date<<->>LocalDateTimeDado:
Date date = [some date](1)
LocalDateTime<<Instant<<Date(2)
Date<<Instant<<LocalDateTimeEjemplo:
Dado:
(1)
LocalDateTime<<Instant<<Date:Crear
InstantdesdeDate:Crear
DatedesdeInstant(no es necesario, pero para ilustración):Crear
LocalDateTimedesdeInstant(2)
Date<<Instant<<LocalDateTimeCrear
InstantdesdeLocalDateTime:Crear
DatedesdeInstant:El resultado es:
fuente
Instant.ofEpochMilli(date.getTime())hacerlodate.toInstant()toInstant()ve bien, excepto que fallajava.sql.Date, ¡arggggh! Entonces, finalmente es más fácil de usarInstant.ofEpochMilli(date.getTime()).Una forma mucho más conveniente si está seguro de que necesita una zona horaria predeterminada:
fuente
lo siguiente parece funcionar cuando se convierte de una nueva API LocalDateTime a java.util.date:
la conversión inversa se puede lograr (con suerte) de manera similar ...
Espero eso ayude...
fuente
Todo esta aquí: http://blog.progs.be/542/date-to-java-time
La respuesta con "ida y vuelta" no es exacta: cuando lo haces
si la zona horaria de su sistema no es UTC / GMT, ¡cambie la hora!
fuente
La forma más rápida para
LocalDateTime->Datees:Date.from(ldt.toInstant(ZoneOffset.UTC))fuente
No estoy seguro de si esta es la manera más simple o mejor, o si hay algún inconveniente, pero funciona:
fuente
LocalDateTimeaDate. En las transiciones de horario de verano, aLocalDateTimepuede ser inexistente o ocurrir dos veces. Necesita resolver lo que quiere que suceda en cada caso.GregorianCalendarpertenece a la antigua API incómoda que la nuevajava.timeAPI tiene como objetivo reemplazarSi está en Android y usa threetenbp , puede usar
DateTimeUtilsen lugar.ex:
no puede usar
Date.fromya que solo es compatible con la API 26+fuente