restar manejo fechas fecha ejemplo java datetime java-8 java-time

manejo - restar fechas en java 8



Conversión entre java.time.LocalDateTime y java.util.Date (7)

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 y hora independiente de la zona horaria.

Probablemente hay millones de líneas de código utilizando la clase heredada java.util.Date para este propósito. Como tal, cuando se conecte el código antiguo con el nuevo, será necesario convertir entre los dos. Como parece que no hay métodos directos para lograr esto, ¿cómo puede hacerse?


Esto es lo que se me ocurrió (y, como en todos los enigmas de Date Time, probablemente será refutado en función de algún ajuste extraño en la zona horaria-leapyear-daylight daylight): D)

Round-tripping: Date <<->> LocalDateTime

Dado: Date date = [some date]

(1) LocalDateTime << Instant << Date

Instant instant = Instant.ofEpochMilli(date.getTime()); LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

(2) Date << Instant << LocalDateTime

Instant instant = ldt.toInstant(ZoneOffset.UTC); Date date = Date.from(instant);

Ejemplo:

Dado:

Date date = new Date(); System.out.println(date + " long: " + date.getTime());

(1) LocalDateTime << Instant << Date :

Crear Instant desde la Date :

Instant instant = Instant.ofEpochMilli(date.getTime()); System.out.println("Instant from Date:/n" + instant);

Crear Date desde Instant (no es necesario, pero para ilustración):

date = Date.from(instant); System.out.println("Date from Instant:/n" + date + " long: " + date.getTime());

Crear LocalDateTime desde Instant

LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC); System.out.println("LocalDateTime from Instant:/n" + ldt);

(2) Date << Instant << LocalDateTime

Crear Instant desde LocalDateTime :

instant = ldt.toInstant(ZoneOffset.UTC); System.out.println("Instant from LocalDateTime:/n" + instant);

Crear Date desde el Instant :

date = Date.from(instant); System.out.println("Date from Instant:/n" + date + " long: " + date.getTime());

La salida es:

Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574 Instant from Date: 2013-11-01T14:13:04.574Z Date from Instant: Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574 LocalDateTime from Instant: 2013-11-01T14:13:04.574 Instant from LocalDateTime: 2013-11-01T14:13:04.574Z Date from Instant: Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574


Lo siguiente parece funcionar cuando se convierte de la nueva API LocalDateTime a java.util.date:

Date.from(ZonedDateTime.of({time as LocalDateTime}, ZoneId.systemDefault()).toInstant());

la conversión inversa se puede (con suerte) lograr de manera similar ...

Espero eso ayude...


No estoy seguro de si esta es la forma más simple o mejor, o si hay alguna trampa, pero funciona:

static public LocalDateTime toLdt(Date date) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(date); ZonedDateTime zdt = cal.toZonedDateTime(); return zdt.toLocalDateTime(); } static public Date fromLdt(LocalDateTime ldt) { ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault()); GregorianCalendar cal = GregorianCalendar.from(zdt); return cal.getTime(); }


Respuesta corta:

Date in = new Date(); LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

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 es un conteo long de milisegundos desde 1970-01-01T00: 00Z (medianoche al comienzo de 1970 GMT / UTC).

La clase equivalente a java.util.Date en JSR-310 es Instant , por lo tanto, existen métodos convenientes para proporcionar la conversión de un lado a otro:

Date input = new Date(); Instant instant = input.toInstant(); Date output = Date.from(instant);

Una instancia java.util.Date no tiene un concepto de zona horaria. Esto puede parecer extraño si llama a toString() en un java.util.Date , porque el toString es relativo a una zona horaria. Sin embargo, ese método realmente utiliza la zona horaria predeterminada de Java sobre la marcha para proporcionar la cadena. La zona horaria no forma parte del estado real de java.util.Date .

An Instant tampoco contiene información sobre la zona horaria. Por lo tanto, para convertir una fecha Instant a una hora local, es necesario especificar una zona horaria. Esta podría ser la zona predeterminada - ZoneId.systemDefault() - o podría ser una zona horaria que controle su aplicación, como una zona horaria desde las preferencias del usuario. LocalDateTime tiene un método de fábrica conveniente que toma tanto el instante como la zona horaria:

Date in = new Date(); LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());

A la inversa, LocalDateTime la zona horaria se especifica llamando al atZone(ZoneId) . El ZonedDateTime se puede convertir directamente a un Instant :

LocalDateTime ldt = ... ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); Date output = Date.from(zdt.toInstant());

Tenga en cuenta que la conversión de LocalDateTime a ZonedDateTime tiene el potencial de introducir un comportamiento inesperado. Esto se debe a que no todas las fechas y horarios 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 se produce dos veces. En primavera, hay un hueco, donde desaparece una hora. Consulte el Javadoc de atZone(ZoneId) para obtener más información sobre lo que hará la conversión.

En resumen, si LocalDateTime un java.util.Date a un LocalDateTime y vuelve a un java.util.Date , puede terminar con un instante diferente debido al horario de verano.

Información adicional: Hay otra diferencia que afectará a fechas muy antiguas. java.util.Date usa un calendario que aparece el 15 de octubre de 1582, con fechas anteriores al calendario juliano en lugar del calendario gregoriano. Por el contrario, java.time.* Utiliza el sistema de calendario ISO (equivalente al gregoriano) para 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.


Si tienes Android y usas threetenbp puedes usar DateTimeUtils lugar.

ex:

Date date = DateTimeUtils.toDate(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

no puedes usar Date.from ya que solo es compatible con api 26+


Todo está aquí: http://blog.progs.be/542/date-to-java-time

La respuesta con "ida y vuelta" no es exacta: cuando lo haces

LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

Si la zona horaria de su sistema no es UTC / GMT, ¡cambia la hora!


Una forma mucho más conveniente si está seguro de que necesita una zona horaria predeterminada:

Date d = java.sql.Timestamp.valueOf( myLocalDateTime );