Me gustaría escribir un script o función para decirme cuántos días a partir de ahora hasta una fecha determinada en el futuro. Lo que me cuesta resolver es cómo procesar la fecha dada y compararla con la fecha actual ... Me estoy imaginando algo así como
read -p "enter the date in the format YYYY-MM-DD "
Y luego asumo que tengo una cadena que no tiene sentido para el shell y tengo que hacer algunas evaluaciones como ... ?? (Esto es solo un ejemplo; supongo bc
que sería necesario)
i=$(($(date +%Y)-${REPLY%%-*}))
j=$(($(date +%m)-${REPLY:5:2}))
k=$(($(date +%d)-${REPLY##*-}))
Y entonces no sé qué hacer con esos números ... ??
if $i > 1 then assign l=$((i*365)) and else what?? # what about leap years?
Using $j somehow assign m # confused before I've started
Using $k somehow assign n # just as bad
echo $((l+m+n))
Seguramente lo estoy haciendo muy difícil para mí; probablemente hay una herramienta de procesamiento de texto que comprende las fechas y puede compararlas.
¿Cómo puedo hacer esto?
Respuestas:
Época de la época
En general, los cálculos sobre el tiempo son más fáciles si nos primera vez se convierten en (Unix) época de tiempo (segundos desde el 01/01/1970). En python, tenemos herramientas para convertir el tiempo en tiempo de época y volver a cualquier formato de fecha que prefieramos.
Simplemente podemos establecer un formato, como:
... y define hoy:
y luego escribe una función para hacer el trabajo:
Entonces la salida de:
... que es, como se mencionó, el número de segundos desde 1-1-1970
Calcular los días entre dos fechas
Si hacemos esto tanto hoy como en nuestra fecha futura, calcule posteriormente la diferencia:
La salida se calculará por fecha , ya que usamos el formato
%Y-%m-%d
. El redondeo en segundos posiblemente daría una diferencia de fecha incorrecta, si estamos cerca de las 24 horas, por ejemplo.Versión terminal
... Y la opción Zenity
Y solo por diversión ...
Una pequeña aplicación. Agréguelo a un acceso directo si lo usa con frecuencia.
La secuencia de comandos:
orangedays.py
Ejecutarlo:
Para envolverlo
Úselo para el pequeño script de aplicación sobre el siguiente
.desktop
archivo:orangedays.desktop
en~/.local/share/applications
En la linea
establecer la ruta real al script ...
fuente
La utilidad GNU
date
es bastante buena en este tipo de cosas. Es capaz de analizar una buena variedad de formatos de fecha y luego generarlos en otro formato. Aquí usamos%s
para generar el número de segundos desde la época. Entonces es una simple cuestión de aritmética restar$now
del$future
y dividir por 86400 segundos / día:fuente
-u
parámetro adate
.Podrías intentar hacer algo
awk
usando lamktime
funciónEl awk espera leer la fecha de la entrada estándar en el formato "AAAA MM DD HH MM SS" y luego imprime la diferencia entre la hora especificada y la hora actual en días.
mktime
simplemente convierte una hora (en el formato especificado) a la cantidad de segundos de una hora de referencia (1970-01-01 00:00:00 UTC); systime simple especifica la hora actual en el mismo formato. Resta uno del otro y obtienes qué tan separados están en segundos. Divide entre 86400 (24 * 60 * 60) para convertir a días.fuente
Aquí hay una versión de Ruby
Ejemplo de ejecución:
A
ruby ./day-difference.rb
continuación se muestra un ejemplo de ejecución del script (suponiendo que lo haya guardado comoday-difference.rb
)Con una fecha futura
Con una fecha pasada
Cuando pasó la fecha de hoy
Aquí hay un buen sitio web para verificar las diferencias de fecha http://www.timeanddate.com/date/duration.html
fuente
Hay un
dateutils
paquete que es muy conveniente para manejar fechas. Lea más sobre esto aquí github: dateutilsInstalarlo por
sudo apt install dateutils
Para su problema, simplemente
dateutils.ddiff <start date> <end date> -f "%d days"
donde la salida se puede elegir como segundos, minutos, horas, días, semanas, meses o años. Se puede usar convenientemente en scripts donde la salida se puede usar para otras tareas.
Por ejemplo,
fuente
Puede usar la biblioteca awk Velour :
O:
fuente
Una solución corta, si ambas fechas pertenecen al mismo año, es:
utilizando el formato "% j", que devuelve la posición de la fecha en días del año, es decir, 135 para la fecha actual. Evita problemas de redondeo y maneja fechas en el pasado, dando resultados negativos.
Sin embargo, cruzando las fronteras del año, esto fallará. Puede sumar (o restar) 365 manualmente para cada año o 366 para cada año bisiesto, si se cruza el último de febrero, pero eso será casi tan detallado como otras soluciones.
Aquí la solución de bash puro:
Shellcheck sugiere muchas citas dobles, pero para los días que excedan el año 9999, debe considerar un enfoque diferente. En el pasado, fallará en silencio para las fechas anteriores a 1970.01.01. La desinfección de la entrada del usuario se deja como un ejercicio para el usuario.
Las dos funciones se pueden refactorizar en una, pero eso podría dificultar su comprensión.
Tenga en cuenta que el script necesita pruebas exhaustivas para manejar correctamente los años bisiestos en el pasado. No apostaría que es correcto.
fuente