Há muitos anos (ainda não existia o Linux nem o bash) escrevi 2 utilitários que venho trazendo comigo:
1 - hton.sh - transforma um horário na qdt de segundos decorridos desde as 00:00h
2 - ntoh.sh - O oposto, transforma um número, no horário correspondente à qdt de segundos decorridos a partir de 00:00h
OBS: Testem antes, pois não uso há muito tempo e posso ter confundido versões
Assim se vc tem 2 horários em h1 e h2, basta fazer ntod.sh $(($(./dton.sh h1) - $(./dton.sh h2)))
$ cat hton.sh
#!/bin/bash
#
# Sintaxe: hton.sh [ hh:mm:ss | hh mm ss ]
#+ Recebe um horario e transforma-o na qtd de segundos a partir de 00:00:00
#+ Caso este horario nao seja informado, a hora atual serah usada como default
#==========================================================
# Quer um curso de Shell em sua empresa?
#+ email para:
address@hidden.
#+ Experiência em mais de 200 turmas
#==========================================================
#
if grep -Eq "^([01]?[0-9]|2[0-3]):[0-5]?[0-9]:[0-5]?[0-9]$" <<< "$*"
then
hh=`echo $1 | cut -f1 -d:`
mm=`echo $1 | cut -f2 -d:`
ss=`echo $1 | cut -f3 -d:`
elif grep -Eq "^([01]?[0-9]|2[0-3]) [0-5]?[0-9] [0-5]?[0-9]$" <<< "$*"
then
hh=$1
mm=$2
ss=$3
elif [ $# -eq 0 ]
then
hh=`date "+%H"`
mm=`date "+%M"`
ss=`date "+%S"`
else
echo "
Uso: $0 [hh:mm:ss|hh mm ss]. Caso nao seja informado
parametro, o horario atual sera usado como default.
" > /dev/tty
exit 1
fi
echo $((hh * 3600 + mm * 60 + ss))
===============================================
$ cat ntoh.sh
#!/bin/bash
#
# Uso: ntoh.sh num (num = qtd de segundo a partir de 00:00:00)
#+ Recebe um numero e transforma-o em um horario no formato
#+ [d] hh:mm:ss, indicando quanto tempo passou a partir de
#+ 00:00:00. Se hora > 24, d receberah a qtd de dias excedentes
#==========================================================
# Quer um curso de Shell em sua empresa?
#+ email para:
address@hidden.
#+ Experiência em mais de 200 turmas
#==========================================================
#
(($# != 1)) && {
echo "
Uso: $0 num (num = qtd de segundo a partir de 00:00:00)
" > /dev/tty
exit 1
}
hh=$(($1 / 3600))
if ((hh >= 24))
then
let a=hh/24
let b=hh%24
hh="$(printf '%02d %02d' $a $b)"
else
hh=$(printf '%02d' $hh)
fi
printf "$hh:%02d:%02d\n" $((($1%3600)/60)) $(($1%60))
==========================================================================
Usei a mesma técnica para trabalhar com datas, veja esses dois:
$ cat dton.sh
#!/bin/bash
#
#======================================================================
# Calcula qtd dias entre uma data passada como parametro e 01/01/1980.
#+ Se nao for passado nenhum parametro a data de hoje sera assumida.
#+ Obs. Para executar este programa sob o sh, trocar os $((..)) por expr
#==========================================================
# Quer um curso de Shell em sua empresa?
#+ email para:
address@hidden.
#+ Experiência em mais de 200 turmas
#==========================================================
#
Data="" +%d/%m/%Y)} # Se não informar a data, pega o default (hoje)
IFS='/' read DFim MFim AFim <<< "$Data"
TotDias=$((1 + 365 * (AFim - 1980) + (AFim - 1980) / 4))
[ $((AFim % 4)) -eq 0 -a $MFim -le 2 ] && TotDias=$((TotDias - 1))
for i in $(cut -f-$MFim -d" " <<< " 31 28 31 30 31 30 31 31 30 31 30 31")
do
TotDias=$((TotDias + $i))
done
echo $((TotDias + DFim))
==================================================================
$ cat ntod.sh
#!/bin/bash
#
#==========================================================
# Recebe uma qtd de dias como parametro, e o transforma em
#+ uma data, que significa 1/1/1980 + parametro recebido.
#+ Obs. Para executar este programa sob o sh, trocar por
#+ $((..)) por expr
#==========================================================
# Quer um curso de Shell em sua empresa?
#+ email para:
address@hidden.
#+ Experiência em mais de 200 turmas
#==========================================================
#
Num=$(($1 - 1))
AFim=$((1980 + (Num / 365)))
DFim=$((Num % 365 - Num / 1460))
[ $((AFim % 4)) -eq 0 ] && DFim=$((DFim + 1))
MFim=1
for i in 31 `[ $((AFim % 4)) -eq 0 ] && echo 29 || echo 28` 31 30 31 30 31 31 30 31 30 31
do
[ $DFim -le $i ] && break
DFim=$((DFim - i))
MFim=$((MFim + 1))
done
[ $DFim -le 0 ] &&
{
AFim=$((AFim - 1))
MFim=12
DFim=$((31+DFim))
}
printf "%02d/%02d/%4d\n" $DFim $MFim $AFim