Las antiguas clases de Java para el manejo de fechas, como Date y Timestamp, han dado muchos dolores de cabeza. Java puso su punto y final hace tiempo, creando una nueva api para sustituirlas. Pero quizás no contaban con que el traspaso de código que usaba unas clases a las nuevas se está haciendo mucho más lento de lo que esperaban. ¿Quieres saber un poco más? Vamos a verlo

Diferencias entre java.sql.Date y java.util.Date

Las diferencias son mínimas. El objeto java.util.Date, digamos que es el objeto «principal», tiene la información en milisegundos de un momento concreto en milisegundos. Representa un Día-Mes-Año Hora-Minuto-Segundo-Milisegundo. Un objeto java.sql.Date, sin embargo, tiene únicamente la información del Día-Mes-Año y la parte de Hora-Minuto-Segundo-Milisegundo la tendría iniciada a 0.

Se diseñó así para facilitar las cosas con las interactuaciones hacia o desde base de datos cuando se quiere trabajar con una fecha. Según la propia documentación de la clase:

A thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE value. A milliseconds value represents the number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.

https://docs.oracle.com/javase/8/docs/api/java/sql/Date.html

No obstante, esto tiene su sentido. En Base de datos es común encontrar el tipo ‘Date‘ y ‘DateTime‘, etc. Java diseñó esta clase en el paquete sql para que al interactuar con bases de datos tuvieramos un objeto Date con la forma de «Date» de una base de datos. Para lo que a un desarrollador suele respectar, si usa alguna de las dos clases será la de java.util el 99% de las veces.

Conversión entre java.sql.Date y java.util.Date

Convertir un java.sql.Date a un java.util.Date y viceversa es directo ya que java.sql.Date es una subclase de java.util.Date. En estos ejemplos puedes ver cómo realizarlo:

De java.sql.Date a java.util.Date:

java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); //Tenemos un objeto originalmente de tipo java.sql.Date
java.util.Date utilDate = new java.util.Date(sqlDate.getTime());

De java.util.Date a java.sql.Date:

java.util.Date utilDate = new java.util.Date(); //Tenemos un objeto originalmente de tipo java.util.Date
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

El uso de Timestamp

Tenemos otra clase en Java, que también parece que sirve para lo mismo. También está incluida en el paquete java.sql y nos referimos a java.sql.Timestamp. Esta clase, al igual que java.sql.Date, es también una subclase de java.util.Date. En este caso, se almacena la información hasta nivel de nanosegundos. Suele relacionarse con los objetos «Timestamp», «DATETIME» de las bases de datos convencionales. Aquí te dejo cómo puedes convertir de java.sql.Timesamp a java.util.Date y viceversa:

De java.util.Date a java.sql.Timestamp

java.util.Date date = new java.util.Date();
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());

De java.sql.Timestamp a java.util.Date:

java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis());
java.util.Date date = timestamp;  

La API Time de Java 8

Java introduce una nueva api para manejar «momentos temporales» en Java 8. Esta API se incluye en el paquete java.time. Tenemos una serie de clases nuevas para trabajar con estos momentos, que son inmutables y tienen una mejor legibilidad y estructura que las originales:

  • Fecha: LocalDate
  • Hora: LocalTime
  • Fecha y Hora: LocalDateTime
  • Un momento concreto en el tiempo: Instant

De un vistazo ya vemos que por el nombre son más claras que las que usábamos habitualmente. Esta nueva API tiene algunas ventajas sobre las clases originales:

  • Inmutabilidad: Las hace segura para multi hilos. (Thread safe)
  • Legibilidad: Tanto el nombre como sus métodos son mucho más claros para humanos que los de la API original
  • Utilidades: Cuenta con gran cantidad de utilidades alrededor (formateadores de fecha, conversores, wrappers..)
  • Soporte para zonas horarias: Permite indicar la zona horaria de cada objeto, facilitando su uso en caso de necesidad.

¿Es fácil convertir nuestros objetos antiguos a los objetos de la nueva API?, vamos a verlo.

Convertir java.util.Date a LocalDate

java.util.Date date = new java.util.Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Convertir java.sql.Date a LocalDate

java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
LocalDate localDate = sqlDate.toLocalDate();

Convertir LocalDate a java.util.Date

LocalDate localDate = LocalDate.now();
java.util.Date date = java.util.Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Con esto hemos visto un poco como manejar estos objetos y su uso principal. No hemos visto todavía, algunos ejemplos de cómo convertir estos objetos entre ellos, a veces necesitamos que pasen por el objeto «Instant». Para que nos entendamos es un poco parecido a cuando convertimos a milisegundos los objetos antiguos.

Convertir LocalDateTime a java.util.Date

Vamos a ver cómo convertir un objeto LocalDate la nueva API a un objeto java.util.Date de la api antigua:

LocalDateTime localDateTime = LocalDateTime.now();
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);

Convertir java.util.Date a LocalDateTime

Ahora vamos a ver cómo convertir un objeto java.util.Date de la api antigua a un objeto LocalDateTime de la nueva api:

Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

Conversiones entre otras clases de la nueva API de tiempo

//LocalDate a LocalDateTime
LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime = localDate.atStartOfDay();  // Comienza a las 00:00 horas del día dado

//LocalDateTime a LocalDate
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();

//LocalDateTime a LocalTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalTime localTime = localDateTime.toLocalTime();

Para terminar, me gustaría recordaros que las clases «old-school» de manejo de tiempos de Java, sigue disponible todavía si necesitas usarla. Ya sea por compatibilidad con alguna librería o el motivo que necesites. Desde Java obviamente recomiendan migrar el uso de dicha API a las nuevas clases cuanto antes para que dejemos de usar los Date, Calendar, Timestamp, etc.. cuanto antes.

Usar esta nueva API te permitirá compatibilizar mejor a futuro ya que las nuevas librerías y nuevos usuarios de las mismas estarán acostumbrados a su uso. Evitarás conversiones si directamente usas estas clases en tu código, así que anímate y cuéntanos que te parece este cambio en los comentarios.

Conversión entre Timestamp y Date en Java
Etiquetado en:    

Deja una respuesta

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

Social media & sharing icons powered by UltimatelySocial