Al desarrollar scripts, a veces es necesario trabajar con fechas utilizando la herramienta GNU date, parte del paquete coreutils. En este artículo voy a explicar cómo restar fechas en Bash, a fin de obtener la cantidad de semanas, días, horas o segundos entre las mismas.



Supongamos que deseamos contar la cantidad de días entre dos fechas, tarea no trivial en absoluto. Por ejemplo, necesitamos contar la cantidad de días desde el 11 de diciembre de 2015 hasta la actualidad.

Utilizando Bash, es posible recurrir al constructor doble paréntesis (( ... )) el cual permite expandir y evaluar expresiones aritméticas.

Para comenzar, vamos a establecer el rango de fechas utilizando dos variables desde (FECHA_INICIO) y hasta (FECHA_FIN):

$ FECHA_INICIO=$(date --date=151211 +%s)
$ FECHA_FIN=$(date +%s)

El formato de ambas fechas consiste en la cantidad de segundos transcurridos desde el primero de enero de 1970 (%s). De esta forma es posible luego restar ambas cantidades de segundos para luego convertir a la unidad deseada.

$ SEGUNDOS=$(( $FECHA_FIN - $FECHA_INICIO ))
$ HORAS=$(( $SEGUNDOS / 3600 ))
$ DIAS=$(( $HORAS / 24 ))
$ SEMANAS=$(( $DIAS / 7 ))

Al día de la fecha (8 de agosto de 2017) el resultado es el siguiente:

root@linuxito:~# date
Tue Aug  8 07:41:25 EDT 2017
root@linuxito:~# FECHA_FIN=$(date +%s)
root@linuxito:~# FECHA_INICIO=$(date --date=151211 +%s)
root@linuxito:~# SEGUNDOS=$(( $FECHA_FIN - $FECHA_INICIO ))
root@linuxito:~# HORAS=$(( $SEGUNDOS / 3600 ))
root@linuxito:~# DIAS=$(( $HORAS / 24 ))
root@linuxito:~# SEMANAS=$(( $DIAS / 7 ))
root@linuxito:~# echo $SEMANAS
86
root@linuxito:~# echo DIAS = $DIAS
DIAS = 606
root@linuxito:~# echo HORAS = $HORAS
HORAS = 14550

Por supuesto es posible utilizar paréntesis y operadores aritméticos y lógicos dentro de la expresión. Por ejemplo, si sólo nos interesa la cantidad de días, es posible resolverlo en una única línea:

root@linuxito:~# FECHA_FIN=$(date +%s)
root@linuxito:~# FECHA_INICIO=$(date --date=151211 +%s)
root@linuxito:~# DIAS=$(( ($FECHA_FIN - $FECHA_INICIO) / (60*60*24) ))
root@linuxito:~# echo $DIAS
606

Además es posible abrir una subshell dentro de la expresión:

root@linuxito:~# DIAS=$(( ($(date +%s) - $(date --date=151211 +%s) / (60*60*24) ))
root@linuxito:~# echo $DIAS
606

Referencias


Tal vez pueda interesarte


Compartí este artículo