Use el tiempo unix en su lugar, date +%sluego reste para obtener la diferencia en segundos.
roblogic
Respuestas:
476
Bash tiene una práctica SECONDSvariable integrada que rastrea la cantidad de segundos que han pasado desde que se inició el shell. Esta variable conserva sus propiedades cuando se le asigna, y el valor devuelto después de la asignación es el número de segundos desde la asignación más el valor asignado.
Por lo tanto, puede establecer SECONDSen 0 antes de comenzar el evento cronometrado, simplemente leer SECONDSdespués del evento y hacer la aritmética del tiempo antes de mostrar.
SECONDS=0# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."
Como esta solución no depende date +%s(que es una extensión GNU), es portátil para todos los sistemas compatibles con Bash.
+1. Por cierto, puedes engañar datepara que realices la aritmética del tiempo por ti, escribiendo date -u -d @"$diff" +'%-Mm %-Ss'. (Eso se interpreta $diffcomo segundos desde la época, y calcula los minutos y segundos en UTC). Sin embargo, eso probablemente no sea más elegante, pero mejor ofuscado. :-P
ruakh
13
Agradable y simple Si alguien necesita horas:echo "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
Chus
66
Debe leer $(date -u +%s)para evitar una condición de carrera en las fechas en que se cambia el horario de verano. Y cuidado con los segundos de salto malvados;)
Tino
3
@ daniel-kamil-kozar Buen hallazgo. Sin embargo, esto es un poco frágil. Solo existe una de esas variables, por lo que no se puede usar de forma recursiva para medir el rendimiento, y lo que es peor, una vez unset SECONDSque desaparece:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
Tino
66
@ParthianShot: Lamento que lo pienses así. Sin embargo, creo que esta respuesta es lo que la mayoría de la gente necesita mientras busca respuestas a una pregunta como esta: para medir cuánto tiempo pasó entre eventos, no para calcular el tiempo.
Daniel Kamil Kozar
99
Segundos
Para medir el tiempo transcurrido (en segundos) necesitamos:
un entero que representa el recuento de segundos transcurridos y
una forma de convertir dicho número entero a un formato utilizable.
Un valor entero de segundos transcurridos:
Hay dos formas internas de bash para encontrar un valor entero para la cantidad de segundos transcurridos:
Variable Bash SECONDS (si SECONDS no está configurado, pierde su propiedad especial).
Establecer el valor de SEGUNDOS en 0:
SECONDS=0
sleep 1# Process to execute
elapsedseconds=$SECONDS
Almacenar el valor de la variable SECONDSal inicio:
a=$SECONDS
sleep 1# Process to execute
elapsedseconds=$(( SECONDS - a ))
Opción Bash printf %(datefmt)T:
a="$(TZ=UTC0 printf '%(%s)T\n' '-1')"### `-1` is the current time
sleep 1### Process to execute
elapsedseconds=$(( $(TZ=UTC0 printf '%(%s)T\n''-1')- a ))
Convierta dicho entero a un formato utilizable
El bash interno printfpuede hacer eso directamente:
%(FORMAT)Tgenera la cadena de fecha y hora resultante de usar FORMAT como una cadena de formato para strftime(3). El argumento asociado es el número de segundos desde Epoch , o -1 (hora actual) o -2 (hora de inicio del shell). Si no se proporciona ningún argumento correspondiente, la hora actual se usa como predeterminada.
Por lo tanto, puede llamar a textifyDuration $elpasedsecondsdonde textifyDurationhay otra implementación de impresión de duración:
Para obtener tiempo formateado, debemos usar una herramienta externa (fecha GNU) de varias maneras para obtener una duración de casi un año e incluir nanosegundos.
Matemáticas dentro de la fecha.
No hay necesidad de aritmética externa, hágalo todo en un solo paso date:
date -u -d "0 $FinalDate seconds - $StartDate seconds"+"%H:%M:%S"
Sí, hay un 0cero en la cadena de comando. Es necesario.
Eso supone que podría cambiar el date +"%T"comando a un date +"%s"comando para que los valores se almacenen (impriman) en segundos.
Tenga en cuenta que el comando se limita a:
Valores positivos de $StartDatey $FinalDatesegundos.
El valor en $FinalDatees mayor (más tarde) que $StartDate.
Diferencia horaria menor a 24 horas.
Acepta un formato de salida con Horas, Minutos y Segundos. Muy facil de cambiar.
Es aceptable usar -u UTC veces. Para evitar "DST" y correcciones de hora local.
Si debe usar la 10:33:56cadena, bueno, simplemente conviértala a segundos,
también, la palabra segundos podría abreviarse como sec:
Si se requiere calcular diferencias de tiempo más largas (hasta 364 días), debemos usar el inicio de (algunos) años como referencia y el valor de formato %j(el número de día en el año):
Similar a:
string1="+10 days 10:33:56.5400022"
string2="+35 days 10:36:10.8800056"StartDate=$(date -u -d "2000/1/1 $string1"+"%s.%N")FinalDate=$(date -u -d "2000/1/1 $string2"+"%s.%N")
date -u -d "2000/1/1 $FinalDate sec - $StartDate sec"+"%j days %H:%M:%S.%N"Output:026 days 00:02:14.340003400
Lamentablemente, en este caso, necesitamos restar 1UNO manualmente del número de días. El comando de fecha ve el primer día del año como 1. No es tan difícil ...
Una herramienta utilizada en dispositivos más pequeños (un ejecutable muy pequeño para instalar): Busybox.
Haga un enlace a busybox llamado fecha:
$ ln -s /bin/busybox date
Úselo luego llamando a esto date(colóquelo en un directorio incluido PATH).
O haga un alias como:
$ alias date='busybox date'
La fecha de Busybox tiene una buena opción: -D para recibir el formato de la hora de entrada. Eso abre muchos formatos para ser utilizados como tiempo. Usando la opción -D podemos convertir el tiempo 10:33:56 directamente:
date -D "%H:%M:%S"-d "10:33:56"+"%Y.%m.%d-%H:%M:%S"
Y como puede ver en la salida del Comando anterior, se supone que el día es "hoy". Para comenzar el tiempo en época:
$ string1="10:33:56"
$ date -u -D "%Y.%m.%d-%H:%M:%S"-d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
La fecha de Busybox puede incluso recibir la hora (en el formato anterior) sin -D:
$ date -u -d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
Y el formato de salida podría ser incluso segundos desde la época.
$ date -u -d "1970.01.01-$string1"+"%s"52436
Para ambas veces, y un poco de matemática bash (busybox todavía no puede hacer las matemáticas):
Esta es una respuesta tan sorprendente que abarca muchas bases y con buenas explicaciones. ¡Gracias!
Devy
Tuve que buscar la %(FORMAT)Tcadena pasada al printfcomando integrado en bash. Desde bash-hackers.org : genera %(FORMAT)Tla cadena de fecha y hora resultante del uso FORMATcomo cadena de formato para strftime (3). El argumento asociado es el número de segundos desde Epoch, o -1 (hora actual) o -2 (hora de inicio del shell). Si no se suministra ningún argumento correspondiente, la hora actual se usa como predeterminada . Eso es esotérico. En este caso, %scomo se da a strftime(3)es "el número de segundos desde la época".
¿Cómo es eso diferente de mi solución? Realmente no puedo ver el beneficio de llamar awken este caso, ya que Bash maneja la aritmética de enteros igualmente bien.
Daniel Kamil Kozar
1
Tu respuesta es correcta también. Algunas personas, como yo, prefieren trabajar con awk que con inconsistencias bash.
Dorian
2
¿Podría dar más detalles sobre las inconsistencias en Bash con respecto a la aritmética de enteros? Me gustaría saber más sobre esto, ya que no sabía nada.
Daniel Kamil Kozar
12
Solo estaba buscando esto. No entiendo las críticas a esta respuesta. Me gusta ver más de una solución a un problema. Y, soy uno que prefiere los awkcomandos a bash (aunque sea por nada más, porque awk funciona en otros shells). Me gustó más esta solución. Pero esa es mi opinión personal.
rpsml
44
Ceros a la izquierda: echo $ ((END-START)) | awk '{printf "% 02d:% 02d \ n", int ($ 1/60), int ($ 1% 60)}'
Estaba buscando algo como tu date método GNU . Genio.
Haohmaru
Por favor, elimine mi comentario ... lo siento
Bill Gale
Después de la instalación a dateutilstravés de apt, no hubo ningún datediffcomando, tuve que usar dateutils.ddiff.
Suzana
12
Me gustaría proponer otra forma que evite recordar el datecomando. Puede ser útil en caso de que ya haya reunido marcas de tiempo en %Tformato de fecha:
ts_get_sec(){
read -r h m s <<< $(echo $1 | tr ':'' ')
echo $(((h*60*60)+(m*60)+s))}
start_ts=10:33:56
stop_ts=10:36:10
START=$(ts_get_sec $start_ts)
STOP=$(ts_get_sec $stop_ts)
DIFF=$((STOP-START))
echo "$((DIFF/60))m $((DIFF%60))s"
incluso podemos manejar milisegundos de la misma manera.
ts_get_msec(){
read -r h m s ms <<< $(echo $1 | tr '.:'' ')
echo $(((h*60*60*1000)+(m*60*1000)+(s*1000)+ms))}
start_ts=10:33:56.104
stop_ts=10:36:10.102
START=$(ts_get_msec $start_ts)
STOP=$(ts_get_msec $stop_ts)
DIFF=$((STOP-START))
min=$((DIFF/(60*1000)))
sec=$(((DIFF%(60*1000))/1000))
ms=$(((DIFF%(60*1000))%1000))
echo "${min}:${sec}.$ms"
¿Hay alguna manera de manejar miliseconos, por ejemplo 10: 33: 56.104
Umesh Rajbhandari
El manejo de milisegundos se comporta mal si el campo de milisegundos comienza con un cero. Por ejemplo, ms = "033" dará los dígitos finales de "027" porque el campo ms se interpreta como octal. cambiar "echo" ... "+ ms))" a ... "+ $ {ms ## + (0)}))" solucionará esto siempre y cuando "shopt -s extglob" aparezca en algún lugar sobre esto en el guión. Probablemente uno también debería quitar los ceros a la izquierda de h, m y s también ...
Eric Towers
3
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))funcionó para mí desde que lleguévalue too great for base (error token is "08")
Niklas
6
Aquí hay algo de magia:
time1=14:30
time2=$( date +%H:%M )# 16:00
diff=$( echo "$time2 - $time1"| sed 's%:%+(1/60)*%g'| bc -l )
echo $diff hours
# outputs 1.5 hours
sedreemplaza a :con una fórmula para convertir a 1/60. Luego, el cálculo del tiempo que realizabc
Aquí hay una solución que usa solo las datecapacidades de comandos usando "ago", y no usando una segunda variable para almacenar el tiempo de finalización:
#!/bin/bash# save the current time
start_time=$( date +%s.%N )# tested program
sleep 1# the current time after the program has finished# minus the time when we started, in seconds.nanoseconds
elapsed_time=$( date +%s.%N --date="$start_time seconds ago")
echo elapsed_time: $elapsed_time
Algunos procesamientos de cadenas pueden eliminar esos valores vacíos
date -ujf%s $(($(date -jf%T "10:36:10"+%s)- $(date -jf%T "10:33:56"+%s))) \
+'%-Hh %-Mm %-Ss'| sed "s/[[:<:]]0[hms] *//g"# 2m 14s
Esto no funcionará si coloca la primera vez primero. Si necesita manejar eso, cambie $(($(date ...) - $(date ...)))a$(echo $(date ...) - $(date ...) | bc | tr -d -)
$ units
2411 units,71 prefixes,33 nonlinear units
You have:(10hr+36min+10s)-(10hr+33min+56s)You want: s
*134/0.0074626866You have:(10hr+36min+10s)-(10hr+33min+56s)You want: min
*2.2333333/0.44776119
Me doy cuenta de que esta es una publicación anterior, pero la encontré hoy mientras trabajaba en un script que tomaría fechas y horas de un archivo de registro y calcularía el delta. La secuencia de comandos a continuación es ciertamente exagerada, y recomiendo comprobar mi lógica y matemáticas.
#!/bin/bash
dTime=""
tmp=""#firstEntry="$(head -n 1 "$LOG" | sed 's/.*] \([0-9: -]\+\).*/\1/')"
firstEntry="2013-01-16 01:56:37"#lastEntry="$(tac "$LOG" | head -n 1 | sed 's/.*] \([0-9: -]\+\).*/\1/')"
lastEntry="2014-09-17 18:24:02"# I like to make the variables easier to parse
firstEntry="${firstEntry//-/ }"
lastEntry="${lastEntry//-/ }"
firstEntry="${firstEntry//:/ }"
lastEntry="${lastEntry//:/ }"# remove the following lines in production
echo "$lastEntry"
echo "$firstEntry"# compute days in last entryfor i in`seq 1 $(echo $lastEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime+31));;4|6|9|11)
dTime=$(($dTime+30));;2)
dTime=$(($dTime+28));;esac}done# do leap year calculations for all years between first and last entryfor i in`seq $(echo $firstEntry|awk '{print $1}') $(echo $lastEntry|awk '{print $1}')`;do{if[ $(($i%4))-eq 0]&&[ $(($i%100))-eq 0]&&[ $(($i%400))-eq 0];then{if["$i"="$(echo $firstEntry|awk '{print $1}')"]&&[ $(echo $firstEntry|awk '{print $2}')-lt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $firstEntry|awk '{print $2}')-eq 2]&&[ $(echo $firstEntry|awk '{print $3}')-lt 29];then{
dTime=$(($dTime+1))}fi}elif[ $(($i%4))-eq 0]&&[ $(($i%100))-ne 0];then{if["$i"="$(echo $lastEntry|awk '{print $1}')"]&&[ $(echo $lastEntry|awk '{print $2}')-gt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $lastEntry|awk '{print $2}')-eq 2]&&[ $(echo $lastEntry|awk '{print $3}')-ne 29];then{
dTime=$(($dTime+1))}fi}fi}done# substract days in first entryfor i in`seq 1 $(echo $firstEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime-31));;4|6|9|11)
dTime=$(($dTime-30));;2)
dTime=$(($dTime-28));;esac}done
dTime=$(($dTime+$(echo $lastEntry|awk '{print $3}')-$(echo $firstEntry|awk '{print $3}')))# The above gives number of days for sample. Now we need hours, minutes, and seconds# As a bit of hackery I just put the stuff in the best order for use in a for loop
dTime="$(($(echo $lastEntry|awk '{print $6}')-$(echo $firstEntry|awk '{print $6}'))) $(($(echo $lastEntry|awk '{print $5}')-$(echo $firstEntry|awk '{print $5}'))) $(($(echo $lastEntry|awk '{print $4}')-$(echo $firstEntry|awk '{print $4}'))) $dTime"
tmp=1for i in $dTime;do{if[ $i -lt 0];then{case"$tmp"in1)
tmp="$(($(echo $dTime|awk '{print $1}')+60)) $(($(echo $dTime|awk '{print $2}')-1))"
dTime="$tmp $(echo $dTime|awk '{print $3""$4}')"
tmp=1;;2)
tmp="$(($(echo $dTime|awk '{print $2}')+60)) $(($(echo $dTime|awk '{print $3}')-1))"
dTime="$(echo $dTime|awk '{print $1}') $tmp $(echo $dTime|awk '{print $4}')"
tmp=2;;3)
tmp="$(($(echo $dTime|awk '{print $3}')+24)) $(($(echo $dTime|awk '{print $4}')-1))"
dTime="$(echo $dTime|awk '{print $1""$2}') $tmp"
tmp=3;;esac}fi
tmp=$(($tmp+1))}done
echo "The sample time is $(echo $dTime|awk '{print $4}') days, $(echo $dTime|awk '{print $3}') hours, $(echo $dTime|awk '{print $2}') minutes, and $(echo $dTime|awk '{print $1}') seconds."
Obtendrá la salida de la siguiente manera.
2012101601563720140917182402The sample time is 700 days,16 hours,27 minutes, and 25 seconds.
Modifiqué un poco el script para que sea independiente (es decir, simplemente establezca valores variables), pero tal vez la idea general también aparezca. Es posible que desee alguna comprobación de error adicional para valores negativos.
Aquí está mi implementación de bash (con bits tomados de otro SO ;-)
function countTimeDiff(){
timeA=$1 # 09:59:35
timeB=$2 # 17:32:55# feeding variables by using read and splitting with IFS
IFS=: read ah am as <<<"$timeA"
IFS=: read bh bm bs <<<"$timeB"# Convert hours to minutes.# The 10# is there to avoid errors with leading zeros# by telling bash that we use base 10
secondsA=$((10#$ah*60*60 + 10#$am*60 + 10#$as))
secondsB=$((10#$bh*60*60 + 10#$bm*60 + 10#$bs))
DIFF_SEC=$((secondsB - secondsA))
echo "The difference is $DIFF_SEC seconds.";
SEC=$(($DIFF_SEC%60))
MIN=$((($DIFF_SEC-$SEC)%3600/60))
HRS=$((($DIFF_SEC-$MIN*60)/3600))
TIME_DIFF="$HRS:$MIN:$SEC";
echo $TIME_DIFF;}
$ countTimeDiff 2:15:552:55:16The difference is 2361 seconds.0:39:21
time
comando?date +%s
luego reste para obtener la diferencia en segundos.Respuestas:
Bash tiene una práctica
SECONDS
variable integrada que rastrea la cantidad de segundos que han pasado desde que se inició el shell. Esta variable conserva sus propiedades cuando se le asigna, y el valor devuelto después de la asignación es el número de segundos desde la asignación más el valor asignado.Por lo tanto, puede establecer
SECONDS
en 0 antes de comenzar el evento cronometrado, simplemente leerSECONDS
después del evento y hacer la aritmética del tiempo antes de mostrar.Como esta solución no depende
date +%s
(que es una extensión GNU), es portátil para todos los sistemas compatibles con Bash.fuente
date
para que realices la aritmética del tiempo por ti, escribiendodate -u -d @"$diff" +'%-Mm %-Ss'
. (Eso se interpreta$diff
como segundos desde la época, y calcula los minutos y segundos en UTC). Sin embargo, eso probablemente no sea más elegante, pero mejor ofuscado. :-Pecho "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
$(date -u +%s)
para evitar una condición de carrera en las fechas en que se cambia el horario de verano. Y cuidado con los segundos de salto malvados;)unset SECONDS
que desaparece:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
Segundos
Para medir el tiempo transcurrido (en segundos) necesitamos:
Un valor entero de segundos transcurridos:
Hay dos formas internas de bash para encontrar un valor entero para la cantidad de segundos transcurridos:
Variable Bash SECONDS (si SECONDS no está configurado, pierde su propiedad especial).
Establecer el valor de SEGUNDOS en 0:
Almacenar el valor de la variable
SECONDS
al inicio:Opción Bash printf
%(datefmt)T
:Convierta dicho entero a un formato utilizable
El bash interno
printf
puede hacer eso directamente:similar
pero esto fallará por más de 24 horas, ya que imprimimos un tiempo de reloj de pared, no realmente una duración:
Para los amantes de los detalles, de bash-hackers.org :
Por lo tanto, puede llamar a
textifyDuration $elpasedseconds
dondetextifyDuration
hay otra implementación de impresión de duración:Fecha GNU.
Para obtener tiempo formateado, debemos usar una herramienta externa (fecha GNU) de varias maneras para obtener una duración de casi un año e incluir nanosegundos.
Matemáticas dentro de la fecha.
No hay necesidad de aritmética externa, hágalo todo en un solo paso
date
:Sí, hay un
0
cero en la cadena de comando. Es necesario.Eso supone que podría cambiar el
date +"%T"
comando a undate +"%s"
comando para que los valores se almacenen (impriman) en segundos.Tenga en cuenta que el comando se limita a:
$StartDate
y$FinalDate
segundos.$FinalDate
es mayor (más tarde) que$StartDate
.Si debe usar la
10:33:56
cadena, bueno, simplemente conviértala a segundos,también, la palabra segundos podría abreviarse como sec:
Tenga en cuenta que la conversión del tiempo de segundos (como se presentó anteriormente) es relativa al comienzo del día "este" (Hoy).
El concepto podría extenderse a nanosegundos, como este:
Si se requiere calcular diferencias de tiempo más largas (hasta 364 días), debemos usar el inicio de (algunos) años como referencia y el valor de formato
%j
(el número de día en el año):Similar a:
Lamentablemente, en este caso, necesitamos restar
1
UNO manualmente del número de días. El comando de fecha ve el primer día del año como 1. No es tan difícil ...El uso de una gran cantidad de segundos es válido y está documentado aquí:
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date
Fecha de Busybox
Una herramienta utilizada en dispositivos más pequeños (un ejecutable muy pequeño para instalar): Busybox.
Haga un enlace a busybox llamado fecha:
Úselo luego llamando a esto
date
(colóquelo en un directorio incluido PATH).O haga un alias como:
La fecha de Busybox tiene una buena opción: -D para recibir el formato de la hora de entrada. Eso abre muchos formatos para ser utilizados como tiempo. Usando la opción -D podemos convertir el tiempo 10:33:56 directamente:
Y como puede ver en la salida del Comando anterior, se supone que el día es "hoy". Para comenzar el tiempo en época:
La fecha de Busybox puede incluso recibir la hora (en el formato anterior) sin -D:
Y el formato de salida podría ser incluso segundos desde la época.
Para ambas veces, y un poco de matemática bash (busybox todavía no puede hacer las matemáticas):
O formateado:
fuente
%(FORMAT)T
cadena pasada alprintf
comando integrado en bash. Desde bash-hackers.org : genera%(FORMAT)T
la cadena de fecha y hora resultante del usoFORMAT
como cadena de formato para strftime (3). El argumento asociado es el número de segundos desde Epoch, o -1 (hora actual) o -2 (hora de inicio del shell). Si no se suministra ningún argumento correspondiente, la hora actual se usa como predeterminada . Eso es esotérico. En este caso,%s
como se da astrftime(3)
es "el número de segundos desde la época".Así es como lo hice:
Realmente simple, tome la cantidad de segundos al comienzo, luego tome la cantidad de segundos al final e imprima la diferencia en minutos: segundos.
fuente
awk
en este caso, ya que Bash maneja la aritmética de enteros igualmente bien.awk
comandos a bash (aunque sea por nada más, porque awk funciona en otros shells). Me gustó más esta solución. Pero esa es mi opinión personal.Otra opción es usar
datediff
desdedateutils
( http://www.fresse.org/dateutils/#datediff ):También podrías usar
gawk
.mawk
1.3.4 también tienestrftime
ymktime
pero versiones anteriores demawk
ynawk
no.O aquí hay otra forma de hacerlo con GNU
date
:fuente
date
método GNU . Genio.dateutils
través de apt, no hubo ningúndatediff
comando, tuve que usardateutils.ddiff
.Me gustaría proponer otra forma que evite recordar el
date
comando. Puede ser útil en caso de que ya haya reunido marcas de tiempo en%T
formato de fecha:incluso podemos manejar milisegundos de la misma manera.
fuente
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))
funcionó para mí desde que lleguévalue too great for base (error token is "08")
Aquí hay algo de magia:
sed
reemplaza a:
con una fórmula para convertir a 1/60. Luego, el cálculo del tiempo que realizabc
fuente
A partir de la fecha (GNU coreutils) 7.4 ahora puede usar -d para hacer aritmética:
Las unidades que puede usar son días, años, meses, horas, minutos y segundos:
fuente
Siguiendo la respuesta de Daniel Kamil Kozar, para mostrar horas / minutos / segundos:
Entonces el guión completo sería:
fuente
O envuélvelo un poco
Entonces esto funciona.
fuente
Aquí hay una solución que usa solo las
date
capacidades de comandos usando "ago", y no usando una segunda variable para almacenar el tiempo de finalización:esto da:
fuente
fuente
date
.date
puede darle la diferencia y formatearla por usted (se muestran las opciones de OS X)Algunos procesamientos de cadenas pueden eliminar esos valores vacíos
Esto no funcionará si coloca la primera vez primero. Si necesita manejar eso, cambie
$(($(date ...) - $(date ...)))
a$(echo $(date ...) - $(date ...) | bc | tr -d -)
fuente
Necesitaba un script de diferencia horaria para usar con
mencoder
(--endpos
es relativo), y mi solución es llamar a un script de Python:fracciones de segundos también son compatibles:
y te puede decir que la diferencia entre 200 y 120 es 1h 20m:
y puede convertir cualquier número (probablemente fraccionario) de segundos o minutos u horas a hh: mm: ss
timediff.py:
fuente
Con GNU
units
:fuente
Generalizando la solución de @ nisetama usando la fecha GNU (confiable Ubuntu 14.04 LTS):
flexible:
fuente
fuente
Defina esta función (digamos en ~ / .bashrc):
Ahora puede medir el tiempo de partes de sus scripts:
Muy útil para encontrar cuellos de botella en la ejecución.
fuente
Me doy cuenta de que esta es una publicación anterior, pero la encontré hoy mientras trabajaba en un script que tomaría fechas y horas de un archivo de registro y calcularía el delta. La secuencia de comandos a continuación es ciertamente exagerada, y recomiendo comprobar mi lógica y matemáticas.
Obtendrá la salida de la siguiente manera.
Modifiqué un poco el script para que sea independiente (es decir, simplemente establezca valores variables), pero tal vez la idea general también aparezca. Es posible que desee alguna comprobación de error adicional para valores negativos.
fuente
No puedo comentar sobre la respuesta de mcaleaa, por lo tanto, publico esto aquí. La variable "diff" debe estar en minúsculas. Aquí hay un ejemplo.
La variable anterior se declaró en minúscula. Esto es lo que sucedió cuando se usa mayúscula.
Entonces, una solución rápida sería así
fuente
Aquí está mi implementación de bash (con bits tomados de otro SO ;-)
No probado, puede tener errores.
fuente