Java Date

Trabajar con fechas en java no es algo del otro mundo ni tiene demasiadas complicaciones, pero la cantidad de formas que hay para hacerlo puede confundirnos, o peor aún, puede que sólo conozcamos la más mala para hacerlo. Con estos artículos pretendo explicar un poco que clases tiene el lenguaje para trabajar con fechas, los métodos más usados y algunas sugerencias para realizar un trabajo adecuado que nos facilite el mantenimiento de nuestras aplicaciones.

1. Las clases java.util.Date y java.sql.Date. Son dos de las clases más usadas cuando una aplicación implica el trabajo con fechas:
java.util.Date: Según la documentación “La clase java.util.Date representa un instante de tiempo específico, con precisión de milisegundos”; esto más que ser una especie de “autoadulación” para la clase, quiere decir que no solo se trata de una simple cadena al estilo yyyy/MM/dd, sino que almacena hasta milisegundos y que es posible trabajar con ellos.
Antes del jdk1.1 la clase java.util.Date tenía dos funciones adicionales a la que conocemos ahora, una de ellas era la interpretación de datos que tenían que ver con fechas, como años, días, segundos, entre otros. La otra era el formateo (la forma como se muestra) y parseo (convertir un String a java.util.Date). Pero debido a las dificultades que presentaban estas funcionalidades a la hora de internacionalizar los programas, esos métodos ya está obsoletos y la clase java.util.Calendar se encargó de esto; así que en este momento esta clase, sólo hace lo que se mencionó al principio: “representa un instante de tiempo específico, con precisión de milisegundos”; más adelante veremos como ampliar esta funcionalidad. Por ahora veamos las convenciones que sigue esta clase:
– El año “y” está representado por un entero igual a (“y” – 1900). Por ejemplo el año 2004 se repressenta como 104 (2004 – 1900).
– Los meses son representados por números entre 0 y 11, donde enero es 0 y diciembre es 11.
– Los días y minutos se representan de forma corriente. Entre 1 – 31 y 0 – 59 respectivamente.
– Las horas van entre 0 y 23, donde la medianoche es 0 y el medio día 12.
– Los segundos van entre 0 y 61. 61 solo ocurre cuando se agrega el segundo adicional para ajustar la diferencia entre el reloj atómico y el tiempo de rotación de la tierra.
No sobra mencionar que los métodos para obtener el año, mes y día de esta clase ya están obsoletos y lo único que hacen es llamar a la clase java.util.Calendar para que esta se encargue de hacerlo (una delegación).

java.sql.Date: Esta clase hereda de java.util.Date y es la representación de la fecha cuando trabajamos con JDBC (Java DabaBase Connectivity), es decir, son los campos almacenados en una base de datos cuyo tipo es una fecha que puede o no incluir la hora, aunque la clase java.sql.Date siempre lo hace. Al igual que su clase padre, tiene una precisión de milisegundos, con la excepción que al mostrarla en la salida estándar con el formato por defecto solo muestra el día, mes y año. Hay que anotar también que para campos que almacenen solamente horas existen otras clases para manejarlos.

En resumen ambas clases, sólo se encargan de almacenar la cantidad de milisegundos que han pasado desde las 12 de la noche del primero de enero de 1970 en el meridiano de Greenwich. Aquí vienen dos puntos importantes:
a) Si la fecha que almacena cualquiera de las clases es menor a las 00:00:00 enero 1 de 1970 GMT, su valor el milisegundos será negativo.
b) La fecha es susceptible a la zona horaria. Por ejemplo en Colombia los milisegundos no se empiezan a contar desde enero 1 de 1970, sino a partir de las 19:00 de diciembre 31 de 1969. Esto es importante por que si transportamos una fecha relativa de una zona a otra, podemos llegar a tener problemas al confiar en los milisegundos que se tienen; además como la clase intenta representar el “Tiempo Universal Coordinado” (UTC) suma 0.9 segundos cada año para ajustar la diferencia entre el reloj atómico y la velocidad de rotación de la tierra. Esto se traduce en que muy dificilmente podemos basarnos en valores como 0 o 60000 para realizar validaciones, pues esos milisegundos no son controlables cuando creamos la instancia de una fecha, peor aún, los milisegundos no son ni siquiera iguales para la misma fecha en la misma zona horaria.

Ambas clases se pueden instanciar directamente mediante new(), pero la clase java.sql.Date necesita un parámetro en el constructor: el tiempo en milisegundos, así que las siguientes instrucciones son válidas:

java.util.Date fechaActual = new java.util.Date(); //Fecha actual del sistema
java.sql.Date inicioLocal = new java.sql.Date(0); //Milisegundo cero

//también se puede crear una instancia de java.util.Date con parámetros iniciales
java.util.Date otraFecha = new java.util.Date(1000); //El primer segundo a partir del inicio

Prueba a imprimir cada uno de estos valores y fíjate en la diferencia de formatos entre java.sql.Date y java.util.Date. Se puede pasar de java.sql.Date a java.util.Date de dos fomas, una de ellas es con una asignación simple:

java.util.Date utilDate = null;
java.sql.Date sqlDate = new java.sql.Date(0);
utilDate = sqlDate;
/* aunque es java.util.Date,
si la imprimes tendrá el formato de java.sql.Date, recordemos que java.sql.Date hereda de
java.util.Date */
System.out.println(utilDate);

También se pueden tomar los milisegundos de java.sql.Date y pasarlos al constructor de java.util.Date:

java.util.Date utilDate = null;
java.sql.Date sqlDate = new java.sql.Date(0);
utilDate = new java.util.Date(sqlDate.getTime());
//esta vez se mostrará con el formato de java.util.Date
System.out.println(utilDate);

Para pasar de java.util.Date a java.sql.Date se deben tomar los milisegundos de la primera y pasarlos al constructor de la segunda:

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
//Con formato de java.sql.Date
System.out.println(sqlDate);

Para comparar fechas usamos el método compareTo() que internamente compara los milisegundos entre ellas usando directamente los métodos getTime() de ambas clases.

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
if (utilDate.compareTo(sqlDate) == 0){
System.out.println(“IGUALES”);
}else{
System.out.println(“DIFERENTES”);
}

O lo que es equivalente:

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
if (utilDate.getTime() == sqlDate.getTime()){
System.out.println(“IGUALES”);
}else{
System.out.println(“DIFERENTES”);
}


Java Colombia. Programación con J2EE, Struts, JSP, EJB a la manera Colombiana

Etiquetas: ,

Anuncios

Blog de programacion Java

Etiquetas: , ,

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!