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.Date
para 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.Date
representa un instante en la línea de tiempo, no una "fecha". Los datos reales almacenados dentro del objeto son unlong
recuento de milisegundos desde 1970-01-01T00: 00Z (medianoche al comienzo de 1970 GMT / UTC).La clase equivalente a
java.util.Date
en JSR-310 esInstant
, por lo tanto, hay métodos convenientes para proporcionar la conversión de aquí para allá:Una
java.util.Date
instancia no tiene concepto de zona horaria. Esto puede parecer extraño si llamatoString()
a unjava.util.Date
, porquetoString
es 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
Instant
tampoco contiene ninguna información sobre la zona horaria. Por lo tanto, para convertirInstant
una 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.LocalDateTime
tiene un método de fábrica conveniente que toma tanto el instante como la zona horaria:A la inversa, la
LocalDateTime
zona horaria se especifica llamando alatZone(ZoneId)
método. LaZonedDateTime
continuación, se puede convertir directamente a unInstant
:Tenga en cuenta que la conversión de
LocalDateTime
aZonedDateTime
tiene 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.Date
a unaLocalDateTime
y de nuevo a unajava.util.Date
que 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.Date
usa 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.Date
no 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:28
utilizar este enfoque. Eche un vistazo a la implementación dejava.sql.Timestamp#toLocalDateTime()
si necesita que el resultado esté1111-11-11 00:00:00
en el ejemplo anterior.java.sql.Date#toInstant
arroja unUnsupportedOperationException
. Así que no lo usestoInstant
en 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
<<->>LocalDateTime
Dado:
Date date = [some date]
(1)
LocalDateTime
<<Instant
<<Date
(2)
Date
<<Instant
<<LocalDateTime
Ejemplo:
Dado:
(1)
LocalDateTime
<<Instant
<<Date
:Crear
Instant
desdeDate
:Crear
Date
desdeInstant
(no es necesario, pero para ilustración):Crear
LocalDateTime
desdeInstant
(2)
Date
<<Instant
<<LocalDateTime
Crear
Instant
desdeLocalDateTime
:Crear
Date
desdeInstant
: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
->Date
es: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
LocalDateTime
aDate
. En las transiciones de horario de verano, aLocalDateTime
puede ser inexistente o ocurrir dos veces. Necesita resolver lo que quiere que suceda en cada caso.GregorianCalendar
pertenece a la antigua API incómoda que la nuevajava.time
API tiene como objetivo reemplazarSi está en Android y usa threetenbp , puede usar
DateTimeUtils
en lugar.ex:
no puede usar
Date.from
ya que solo es compatible con la API 26+fuente