A menudo quiero hacer algunos cálculos rápidos de fechas, como:
- ¿Cuál es la diferencia entre estas dos fechas?
- ¿Cuál es la fecha n semanas después de esta otra fecha?
Normalmente abro un calendario y cuento los días, pero creo que debería haber un programa / script que pueda usar para hacer este tipo de cálculos. ¿Alguna sugerencia?
Respuestas:
Las "n semanas después de una fecha" son fáciles con la fecha GNU (1):
No conozco una manera simple de calcular la diferencia entre dos fechas, pero puede ajustar una pequeña lógica alrededor de la fecha (1) con una función de shell.
Cambie
d1
yd2
si desea el cálculo de la fecha de la otra manera, o sea un poco más elegante para que no importe. Además, en caso de que haya una transición que no sea DST a DST en el intervalo, uno de los días durará solo 23 horas; puede compensar agregando ½ día a la suma.fuente
Para un conjunto de herramientas portátiles, pruebe mis propias dateutils . Sus dos ejemplos se reducirían a frases sencillas:
o en semanas y días:
y
fuente
dateadd -i '%m%d%Y' 01012015 +1d
no parece funcionar, simplemente cuelga allí indefinidamente ... funciona si las especificaciones de fecha están separadas por un carácter, cualquier carácter ... ¿alguna idea de lo que está mal?)Un ejemplo de Python para calcular la cantidad de días que he caminado por el planeta:
fuente
ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days"
12813
ychaouche@ychaouche-PC ~ $
Por lo general, prefiero tener la hora / fecha en formato unix utime (número de segundos desde la época, cuando comenzaron los setenta, UTC). De esa forma, siempre se reduce a una simple sustracción o adición de segundos.
El problema suele ser transformar una fecha / hora en este formato.
En un entorno de shell / script puede obtenerlo.
date '+%s'
Al momento de escribir, la hora actual es1321358027
.Para comparar con 2011-11-04 (mi cumpleaños)
date '+%s' -d 2011-11-04
, cediendo1320361200
. Restar:expr 1321358027 - 1320361200
da996827
segundos, que esexpr 996827 / 86400
= hace 11 días.La conversión de utime (formato 1320361200) a una fecha es muy simple, por ejemplo, en C, PHP o perl, usando bibliotecas estándar. Con GNU
date
, el-d
argumento puede anteponerse@
para indicar el formato "Segundos desde la época".fuente
date -d @1234567890
convierte de segundos desde la época a cualquier formato de fecha que especifique.info date
, sobre todo los segundos desde la época de nodo: “Si preceden a un número con '@', esto representa un sello de tiempo interno como un recuento de segundos.”Si una herramienta gráfica está bien para usted, lo recomiendo
qalculate
(una calculadora con énfasis en las conversiones de unidades, viene con una interfaz GTK y KDE, IIRC). Ahí puedes decir, por ejemplopara obtener el número de días (140, ya que 1900 no fue un año bisiesto) entre las fechas, pero, por supuesto, también puede hacer lo mismo por momentos:
produce
8.4591667
horas o, si se establece la salida de formato de tiempo,8:27:33
.fuente
qalc
entonceshelp days
.qcalc
ejemplo:qalc -t 'days(1900-05-21, 1900-01-01)'
-> 140Esto surgió cuando se usa
date -d "$death_date - $y years - $m months - $d days"
para obtener una fecha de nacimiento (para genealogía). Ese comando es INCORRECTO. Meses no son todos de la misma longitud, por lo que(date + offset) - offset != date
. Las edades, en año / mes / día, son medidas que van desde la fecha de nacimiento.La fecha da el resultado correcto en ambos casos, pero en el segundo caso estaba haciendo la pregunta incorrecta. Importa QUÉ 11 meses del año cubren +/- 11, antes de sumar / restar días. Por ejemplo:
Para que la resta sea la operación inversa de sumar, el orden de las operaciones debería invertirse. Agregar agrega años, ENTONCES meses, ENTONCES días. Si restar usa el orden opuesto, entonces volverías a tu punto de partida. No lo hace, por lo que no lo hace, si el desplazamiento de días cruza el límite de un mes en un mes de duración diferente.
Si necesita trabajar hacia atrás desde una fecha y edad de finalización, puede hacerlo con múltiples invocaciones de
date
. Primero reste los días, luego los meses, luego los años. (No creo que sea seguro combinar los años y los meses en una soladate
invocación, debido a que los años bisiestos alteran la duración de febrero).fuente
Otra forma de calcular la diferencia entre dos fechas del mismo año calendario podría usar esto:
date
a la variable DATEfirstnum. El-d
indicador muestra la cadena en un formato de hora en este caso el 14 de mayo de 2014 y+"%j"
le indicadate
que formatee la salida solo el día del año (1-365).DAYSdif
a la diferencia de los dos días.DAYSdif
.Esto funciona con la versión GNU de
date
, pero no con la versión PC-BSD / FreeBSD. Lo instalécoreutils
desde el árbol de puertos y usé el comando en su/usr/local/bin/gdate
lugar.fuente
DATEfirstnum=$(date -d "$1" +%s)
DATElastnum=$(date -d "$2" +%s)
Además, este script no podrá calcular la diferencia entre dos años diferentes.+%j
se refiere al día del año (001..366), por lo que las./date_difference.sh 12/31/2001 12/30/2014
salidas -1. Como han señalado otras respuestas, debe convertir ambas fechas en segundos desde 1970-01-01 00:00:00 UTC.$
una expresión aritmética interna:$((DATElastnum - DATEfirstnum))
también funcionará.Con frecuencia uso SQL para cálculos de fechas. Por ejemplo MySQL , PostgreSQL o SQLite :
Otras veces me siento de humor para JavaScript. Por ejemplo SpiderMonkey , WebKit , Seed o Node.js :
(Tenga cuidado al pasar el mes al
Date
constructor del objeto JavaScript . Comienza con 0.)fuente
Con la ayuda de las soluciones de dannas, esto se puede hacer en una línea con el siguiente código:
(Funciona tanto en Python 2.xy Python 3.)
fuente
date
y bash puede hacer diferencias de fecha (se muestran las opciones de OS X). Coloque la última fecha primero.fuente
También hay cálculos de tiempo de la unidad GNU combinados con la fecha GNU:
(gunits son unidades en Linux, gdate es fecha)
fuente
dateiff.sh en github: gist
fuente
La respuesta de Camh se ocupa de la mayor parte, pero podemos mejorar para hacer frente al redondeo, zonas horarias, etc. Además, obtenemos algo de precisión adicional y la capacidad de elegir nuestras unidades:
-d
dicedate
que estamos proporcionando una fecha y hora para convertir.+%s.%N
cambia la fecha y hora a segundos.nanosegundos desde 1970-01-01 00:00:00 UTC.bc
calcula la diferencia entre los dos números, y el factor de división nos da las diferentes unidades.printf
agrega un 0 antes del decimal si es necesario (bc
no lo hace) y asegura que el redondeo vaya al más cercano (bc
solo se trunca). También podrías usarawk
.Ahora ejecutemos esto con un caso de prueba funky,
Tenga en cuenta que dado que la duración de un mes o año no siempre es la misma, no hay una sola respuesta "correcta" allí, aunque hoy en día se podría usar 365.24 días como una aproximación razonable.
fuente
Puede usar la biblioteca awk Velour :
O:
Resultado:
fuente