Java Dates y Times después de Java 8

time-after-java8

time-after-java8


El tratamiento de java dates y times después de Java 8 se ha simplificado mucho. Ayudando al desarrollador y evitando tareas más complejas, así como no hacer uso de librerías de terceros.

Algunas de las mejoras que se han aportado han sido:

  • Thread Safe: Los objetos Date y Calendar no eran thread safe, con lo que para evitar este problema, la nueva API es inmutable y thread safe.
  • Nuevo y mejorado diseño del API: El antiguo API de fechas era más complicado y difícil. En esta versión se ha mejorado el entendimiento y facilitado su uso.
  • TimeZone: Con la nueva API se simplifica el uso para TimeZone.

LocalDate, LocalDateTime y LocalTime

Estas son las clases más comunes que se van a usar en cualquier proyecto. LocalDate representa una fecha sin tiempo; LocalTime que representa una hora y LocalDateTime que nos proporciona una fecha y hora. Mostrarán fecha y hora de nuestro zona horaria.

Vamos con unos cuantos ejemplos:

LocalDate currentDay = LocalDate.now(); (1)
LocalTime currentTime = LocalTime.now();actual (2)
LocalDateTime currentDateAndTime = LocalDateTime.now();  (3)

En el ejemplo anterior, tendríamos:

  • (1) La fecha de ese momento
  • (2) La hora de ese momento
  • (3) Fecha y hora de ese momento.

¿Cómo hacemos si queremos una fecha y hora concreta?

LocalDate day = LocalDate.of(2020,3,3); (1)
LocalTime time = LocalTime.of(6,30); (2)
LocalDateTime dateAndTime = LocalDateTime.now(2020,3,3,6,30);  (3)

Según el ejemplo anterior:

  • (1) Fecha 3 de Marzo de 2020
  • (2) Hora 6:30
  • (3) Fecha 3 de Marzo de 2020 a las 6:30

Convertir de LocalDateTime a LocalDate y LocalTime:

LocalDateTime dateAndTime = LocalDateTime.now(2020,3,3,6,30);  
LocalDate localDate = dateAndTime.toLocalDate();
LocalTime localTime = dateAndTime.toLocalTime();

También podemos usar un DateTImeFormatter.ISO_LOCAL_DATE_TIME de la siguiente manera:

LocalDateTime dateTime = LocalDateTime.parse("2020-01-10T06:30");

Por ahora, estamos viendo que el uso de esta API es realmente sencilla, vamos a incrementar o decrementar horas y días:

LocalDate date = LocalDate.now().minusDays(1L);
LocalDate date2 = LocalDate.now().plusDays(1L);
LocalDate date3 = LocalDate.now().plusDays(2L, ChronoUnit.Days);

LocalTime time1 = LocalTime.now().plusMinutes(1L);
LocalTime time2 = LocalTime.now().minusMinutes(2L);
LocalTime time3 = LocalTime.now().plusMinutes(2L, ChronoUnit.Minutes);

Ahora vamos a volver al formato antiguo de fechas con Date() y viceversa, y vamos a hacer conversiones. Aunque LocalDate, LocalTime y LocalDateTime , no contiene ningún tipo de información de Zone o de Offset, como vamos a hacer uso de Instant, necesitamos proporcionar un offset.

Date now = new Date(); // fecha 1 de Abril 2 semanas de confinamiento
LocalDateTime currentDate = LocalDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault()); 

Date date = Date.from(currentDate.toInstant(ZoneOffset.ofHours(1)));
Date date = Date.from(currentDate.toInstant(ZoneId.systemDefault().getRules().getOffset(currentDate)));

Trabajando con Duration y Period

Ambos, tanto Duration como Period, son representaciones de tiempo entre dos fechas.

Ejemplo con Period, es utilizado para obtener tiempo entre dos LocalDate:

LocalDate firstDayOfQuarantine = LocalDate.parse("2020-03-15");
LocalDate lastDayOfQuarantine = LocalDate.parse("2020-04-14");
int totalDaysOfQuarantine = Period.between(firstDayOfQuarantine, lastDayOfQuarantine).getDays();

Ejemplo con Duration, suele ser usado para obtener tiempo entre objetos LocalTime:

LocalTime currentTime = LocalTime.now();
LocalTime finalTime = LocalTime.now().plusMinutes(5L);
long total = Duration.between(currentTime, finalTime).getSeconds();

Trabajando con ZoneDateTime y OffsetDateTime

Java 8 nos trajo la clase ZoneDateTime para cuando hay que trabajar con zonas concretas, hay unas 40 zonas diferentes y gracias al ZoneId, podemos seleccionar la zona.

ZoneId zoneId = ZoneId.of("Europe/Paris");

Convirtiendo una hora una zona:

LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);

También podemos hacer uso de un parseador:

ZonedDateTime.parse("2020-04-01T12:15:30+01:00[Europe/Paris]");

También podemos utilizar el OffsetDateTime para trabajar con zonas. La clase OffsetDateTime es una inmutable representación de un objeto date-time con offset.

LocalDateTime localDateTime = LocalDateTime.now();

Ahora añadimos 3 horas creando una ZoneOffset:

ZoneOffset zoneOffset = ZoneOffset.of("+03:00");
OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, zoneOffset);

Tras esto tendríamos un LocalDateTime de 2020-04-01 20:01 +3:00.

Usando formateadores para las fechas

Ya que alrededor del mundo, usamos diferentes formatos para las fechas, se hace necesario hacer uso de formateadores. En el ejemplo siguiente, vamos a probar varios formatos:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd][dd/MM/yyyy][MM-dd-yyyy]");
LocalDate.parse("04-04-2020", formatter);
LocalDate.parse("04/04/2028", formatter);
LocalDate.parse("2020-04-04", formatter);

Al definir todos los formateadores de la forma anterior, podemos ir utilizando el formateador, en función de lo que queramos parsear.

¿Podríamos dar formato solo a alguna parte? Sí, de la siguiente manera:

<br>DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-[MM-dd][MMM-dd]" );
LocalDate.parse( "2020-04-04", formatter );
LocalDate.parse( "2018-Apr-04", formatter );

Conclusión de Java Dates y Times después de Java 8

Hemos podido ver una introducción del API de fechas que fue introducida en Java 8. Como se ha podido apreciar, ha hecho mucho más fácil el trabajar con fechas, facilitando el trabajo al desarrollador.

Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com y te ayudaremos encantados!


No te olvides de seguirnos en nuestras redes sociales Facebook o Twitter para estar actualizado.


1 pensamiento sobre “Java Dates y Times después de Java 8

Deja una respuesta

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