En programación el manejo del tiempo y las fechas en Java es un tema muy interesante, pues cada programador tendrá su manera particular de hacerlo. Yo escribiré este post con base en mi experiencia en el desarrollo de algoritmos de programación.
En Java existen varios tipos de «datos primitivos», entre los cuales se encuentra la clase Date. Para crear un objeto de la clase Date, hacemos lo siguiente:
1 |
Date dt = new Date(); |
En este ejemplo, el objeto dt es una instancia de la clase Date. ¿Qué información contiene ese objeto? Pues una manera de extraer esa información es a través de la clase SimpleDateFormat.
En el siguiente ejemplo voy a crear un objeto de la clase Date y voy a imprimir en consola el contenido de ese objeto. El código es el siguiente:
1 2 3 4 5 |
public static void main(String[] args) { Date dt = new Date(); System.out.println("Fecha y hora: "+ new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").format(dt)); } |
El resultado de ejecutar este código es el siguiente:
Procedo a explicar lo que sucedió:
- Cuando uno crea un objeto de la clase Date (como dt), ese objeto automáticamente asume el valor del instante de tiempo en el que se ejecuta el código. En mi caso, ejecuté este código el 15 de agosto de 2021 a las 10 de la mañana, 24 minutos y 8 segundos. Si ejecuto el código de nuevo, en la consola aparecerá un resultado distinto.
- Para extraer los datos del objeto dt se utiliza la clase SimpleDateFormat, la cual posee el método format(). Ese método convierte los objetos de la clase Date en cadenas de caracteres (String) siguiendo el formato proporcionado en el constructor de la clase. En este caso el parámetro que utilicé en el constructor de la clase fue «dd/MM/yyyy hh:mm:ss«. Esos parámetros significan: «día/mes/año hora:minutos:segundos».
A continuación presentaré para ustedes los parámetros que se pueden utilizar en el constructor de la clase SimpleDateFormat:
Param. | Descripción | Tipo de dato | Ejemplo |
---|---|---|---|
G |
Designador de era | Text | AD |
y |
Año | Year | 1996 ; 96 |
Y |
Año | Year | 2009 ; 09 |
M |
Mes del año | Month | July ; Jul ; 07 |
w |
Semana del año | Number | 27 |
W |
Semana del mes | Number | 2 |
D |
Día del año | Number | 189 |
d |
Día del mes | Number | 10 |
F |
Día de la semana en el mes | Number | 2 |
E |
Nombre del día | Text | Tuesday ; Tue |
u |
Número de día de semana | Number | 1 |
a |
Marcador am/pm | Text | PM |
H |
Hora del día (0-23) | Number | 0 |
k |
Hora del día (1-24) | Number | 24 |
K |
Hora am/pm (0-11) | Number | 0 |
h |
Hora am/pm (1-12) | Number | 12 |
m |
Minuto en hora | Number | 30 |
s |
Segundos en minutos | Number | 55 |
S |
Milisegundos | Number | 978 |
z |
Zona horaria | General time zone | Pacific Standard Time ; PST ; GMT-08:00 |
Z |
Zona horaria | RFC 822 time zone | -0800 |
X |
Zona horaria | ISO 8601 time zone | -08 ; -0800 ; -08:00 |
Con estos parámetros podemos lograr que la fecha y la hora en Java adopte el formato que necesitemos. Por ejemplo, si en el ejemplo mostrado anteriormente quiero que la hora esté en formato de 24 horas (siendo 0 las 12 AM y 23 las 11 PM), el código a utilizar es el siguiente:
1 2 3 4 5 |
public static void main(String[] args) { Date dt = new Date(); System.out.println("Fecha y hora: "+ new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(dt)); } |
Simplemente cambié la «hh» por «HH» en los parámetros del constructor de la clase SimpleDateFormat. El resultado es:
Con los parámetros mostrado en la tabla de arriba podemos darle la forma que queramos a las fechas en Java. Los «:» y los «/» no forman parte de los parámetros, sino que formatean la salida de texto en un formato sencillo de comprender para los usuarios.
Creación de objetos con fechas específicas
Si queremos crear un objeto con una fecha específica tendremos que usar el método parse() de la clase SimpleDateFormat. Con ese método se pueden convertir Strings en Date, lo cual resulta muy útil en algunos casos.
Por ejemplo, si queremos crear un objeto de la clase Date con la fecha 27 de octubre de 2017 a las 12:03 AM, haremos lo siguiente:
1 2 3 4 5 6 |
try { Date dt = new SimpleDateFormat("dd/MM/yyyy HH:mm") .parse("27/10/2017 00:03"); } catch (ParseException ex) { Logger.getLogger(Test_class.class.getName()).log(Level.SEVERE, null, ex); } |
Esta instrucción podría lanzar un error, así que debe estar dentro de un Try Catch. Con el código aquí mostrado tendremos un objeto de la clase Date que contiene la fecha que especificamos en formato de texto. Es importante que la fecha que proporcionamos tenga el mismo formato que los parámetros que usamos en el constructor de la clase SimpleDateFormat.
Los timestamp en Java
Como ya hemos visto, el uso de la clase Date no es tan sencillo. En un objeto date se pueden guardar tanto días como horas. Nosotros conocemos como fecha a una combinación de día/mes/año. Las horas son una combinación de horas:minutos:segundos. En caso de ser necesario, podríamos crear un objeto Date con la información completa de un «instante» de tiempo. Esto sería, la combinación de día, mes, año, hora, minutos, segundos y milisegundos.
En un objeto Date se puede guardar mucha información, pero puede llegar a ser complicado. A veces resulta más fácil convertir las fechas en un número entero y trabajar con números en vez de todos los componentes de las fechas. Para ello existen los timestamp. Los llamados «epochs».
Un epoch es un número que representa un instante de tiempo. Está compuesto por la cantidad de milisegundos que ha transcurrido desde las 00:00:00.00 horas del 1 de enero de 1970. Naturalmente, los epochs son números muy grandes.
Por ejemplo, el epoch del momento en el que estoy escribiendo este párrafo es 1629341105218, dado en milisegundos. Voy a tratar de convertir ese número en una fecha en Java. El código es el siguiente:
1 2 3 4 |
Date dt = new Date(); dt.setTime(1629341105218L); System.out.println("Fecha y hora: " + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(dt)); |
Este código debería producir la siguiente salida:
La «L» que se pone al final del número de milisegundos es para indicar que se trata de un dato tipo Long.
Con las fechas en formato epoch es más fácil hacer operaciones con fechas, tales como sumar o restar días u horas, minutos o segundos. Por ejemplo, si quiero restarle un día a la fecha del ejemplo anterior, haría lo siguiente:
1 2 3 4 5 6 |
Date dt = new Date(); Long epoch = 1629341105218L; epoch = epoch - 86400000; dt.setTime(epoch); System.out.println("Fecha y hora: " + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(dt)); |
Al restarle 864000000 al epoch, estoy quitándole la cantidad de milisegundos que contiene un día. También podemos quitarle o agregarle horas (restándole 3600000), minutos (60000), segundos (1000), semanas, meses, etc.
Los timespamp en formato epoch también son muy útiles en el manejo de bases de datos, pues es más sencillo guardar un número que un conjunto de caracteres que necesitan ser interpretados de una manera específica. El epoch es una de las notaciones de tiempo más universales que se pueden utilizar en el desarrollo de software y en el manejo de información.
Diferencia entre fechas
Para calcular la diferencia entre fechas en Java existe una gran variedad de técnicas, tanto con los recursos nativos como con librerías externas. Utilizando las clases Date y SimpleDateFormat podemos lograrlo fácilmente. Veamos un ejemplo:
1 2 3 4 5 6 7 8 9 10 |
try { SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); Date firstDate = format.parse("30/07/1992"); Date secondDate = format.parse("27/10/2017"); long timeDiff = Math.abs(secondDate.getTime() - firstDate.getTime()); long days = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS); System.out.println("Diferencia en días: "+days); } catch (ParseException ex) { Logger.getLogger(Test_class.class.getName()).log(Level.SEVERE, null, ex); } |
El resultado de este código es el siguiente:
Las diferencias de tiempo pueden expresarse en días (ver ejemplo), horas, minutos, segundos, milisegundos y nanosegundos. Para más posibilidades en el cálculo de diferencia entre fechas se puede utilizar librerías externas diseñadas para este propósito.
Espero que la información presentada aquí sea de utilidad para ustedes. Cualquier duda o sugerencia me la pueden hacer llegar a través de la caja de comentarios.