[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [shell-script] Calcular diferença entre dias...
From: |
Daniel Henrique Angst |
Subject: |
Re: [shell-script] Calcular diferença entre dias... |
Date: |
Thu, 07 Sep 2006 18:37:38 -0300 |
User-agent: |
Thunderbird 1.5.0.4 (X11/20060516) |
Boa tarde.
Eu mandei o script em anexo, mas o mesmo não chegou.
Por isso estou mandando ele de novo, mas dessa vez no corpo da mensagem.
Era isso.
#!/bin/sh
# Autor: Daniel Angst
# Data: 09 de Fevereiro de 2006
# Calcula a diferenca de data
#
# Funcionamento:
# Esse script verifica a diferenca entre as datas passadas. Se houver
diferenca, ele analisa aonde esta a diferenca, ou seja,
# se eh de minutos, horas, dias, meses e anos.
# O calculo eh feito baseado em minutos. Ou seja, as datas passadas sao
convertidas em minutos, e a diferenca
# eh convertida em anos, dias , horas, minuto
# Formato da Data:
# DDMMAAAAhhmm
# Meses com 31 dias
# 1,3,5,7,8,10,12
# Meses com 30 dias
# 4,6,9,11
# Mes de fevereiro
# 2
# Dias acumulados no ano, levando em conta se o ano eh bisexto ou nao
acumulado_ano()
{
ano=$1
mes=$2
dia=$3
cal 2 $ano | grep 29 > /dev/null
resposta=`echo $?`
if [ $resposta = 0 ] ; then
bisexto=sim
else
bisexto=nao
fi
if [ $bisexto = nao ] ; then
fevtmp=28
else
fevtmp=29
fi
jan=31
fev=$fevtmp
mar=31
abr=30
mai=31
jun=30
jul=31
ago=31
set=30
out=31
nov=30
dez=31
# Faz o acumulado de dias desde o inicio do ano ate o ultimo mes cheio
case $mes in
01)mestmp=$dia ;;
02)mestmp=`echo $jan \+ $dia | bc `;;
03)mestmp=`echo $jan \+ $fev \+ $dia | bc ` ;;
04)mestmp=`echo $jan \+ $fev \+ $mar \+ $dia | bc ` ;;
05)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $dia | bc ` ;;
06)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $dia | bc ` ;;
07)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $dia |
bc ` ;;
08)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $jul \+
$dia | bc ` ;;
09)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $jul \+
$ago \+ $dia | bc ` ;;
10)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $jul \+
$ago \+ $set \+ $dia | bc ` ;;
11)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $jul \+
$ago \+ $set \+ $out \+ $dia | bc ` ;;
12)mestmp=`echo $jan \+ $fev \+ $mar \+ $abr \+ $mai \+ $jun \+ $jul \+
$ago \+ $set \+ $out \+ $nov \+ $dia | bc ` ;;
esac
# Remove 1 dia por o dia corrente nao eh dia completo.
echo $mestmp \- 1|bc > diasano
}
# Essa funcao converte para minutos a data informada
converte()
{
# Parametros da funcao
# 1=[0|1]: 0 - Ano igual; 1- Ano diferente
# 2=hora
# 3=minuto
# 4=dia
# 5=mes
# 6=ano
parametros=`echo $#`
if [ $parametros = 3 ] ; then
# ano,mes,dia iguais
hora=$2
min=$3
conver=`echo $hora \* 60 |bc`
echo $conver + $min | bc > tmpmin
fi
if [ $parametros = 4 ] ; then
# ano e mes iguais.
hora=$2
min=$3
dia=$4
# Calcula o nru de minutos decorridos considerando dia cheio
diacheio=`echo $dia \- 1 |bc`
if [ $diacheio = 0 ] ; then
# Dia 1 do mes
conver=`echo $hora \* 60 |bc`
echo $conver + $min | bc > tmpmin
else
conver_dia_minutos=`echo \(\( $diacheio \* 24\) \* 60\) | bc` #
Converte o nro completo de dias em minutos
conver=`echo $hora \* 60 |bc`
echo $conver + $min + $conver_dia_minutos | bc > tmpmin
fi
fi
if [ $parametros = 6 ] && [ $1 = 0 ] ; then
# Apenas o ano eh o mesmo
# O calculo eh baseado em quantos minutos ja decorreram do ano
hora=$2
min=$3
dia=$4
mes=$5
ano=$6
# Funcao que devolve o nro de dias ja decorridos no ano
acumulado_ano $ano $mes $dia
nrodiascompletos=`cat diasano`
rm diasano
nrominutostmp=`echo $nrodiascompletos \* 1440 | bc`
conver=`echo $hora \* 60 |bc`
echo $conver \+ $min \+ $nrominutostmp | bc > tmpmin
fi
}
# Essa funcao calcula a diferenca entre os parametros passados
difmin()
{
min1=$1
min2=$2
diff=`echo $min2 \- $min1 | bc`
if [ $diff = 1440 ] ; then
echo 1 dia
fi
if [ $diff -lt 1440 ] ; then
# Existe menos de 1 dia de diferenca
if [ $diff -lt 60 ] ; then
# A diferenca eh de menos de 1h.
echo "$diff minutos"
fi
if [ $diff -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diff
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diff - $horascheias | bc`
if [ $minutos = 0 ] ; then
echo "$horas horas"
else
echo "$horas horas e $minutos minutos"
fi
fi
fi
if [ $diff -gt 1440 ] ; then
# Verifica quantos dias cheios
dias=0
result=$diff
while [ $result -gt 1440 ] || [ $result = 1440 ]
do
result=`echo $result \- 1440 | bc`
dias=`echo $dias \+ 1 | bc`
done
diascheios=`echo $dias \* 1440 | bc`
diffhoras=`echo $diff \- $diascheios | bc` # horas que faltam serem
calculadas
if [ $diffhoras = 0 ] ; then
echo "$dias dias"
fi
if [ $diffhoras -lt 60 ] ; then
# Tem menos de uma hora cheia a diferenca
echo $dias dias e $diffhoras minutos
fi
if [ $diffhoras -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diffhoras
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diffhoras - $horascheias | bc`
if [ $minutos = 0 ] && [ $horas = 0 ] ; then
echo "$dias dias"
fi
if [ $minutos -gt 0 ] && [ $horas = 0 ] ; then
echo "$dias dias e $minutos minutos"
fi
if [ $minutos = 0 ] && [ $horas -gt 0 ] ; then
echo "$dias dias e $horas horas"
fi
if [ $minutos -gt 0 ] && [ $horas -gt 0 ] ; then
echo "$dias dias e $horas horas e $minutos minutos"
fi
fi
fi
}
# Funcao que calcula a diferenca de data quando o ano eh diferente
difmin2()
{
# parametros
# 1- Tempo1
# 2- Tempo2
# 3- ano1
# 4- ano2
tempo1=$1
tempo2=$2
ano1=$3
ano2=$4
# O calculo eh feito de duas formas.
# A 1 eh quando a diferenca eh de um ano. A segunda eh de quando a
diferenca eh de mais de um ano
difano=`echo $ano2 - $ano1 | bc`
if [ $difano = 1 ] ; then
# verifica se o ano da data1 eh bisexto. Calcula o nru. de minutos do ano
cal 2 $ano | grep 29 > /dev/null
resposta=`echo $?`
if [ $resposta = 0 ] ; then
#bisexto=sim
totalano=`echo 366 \* 24 \* 60 | bc`
else
#bisexto=nao
totalano=`echo 365 \* 24 \* 60 | bc`
fi
# Calcula a diferenca de tempo decorrido desde a data1 final ate o
fim do ano
tempodecorrido1=`echo $totalano \- $tempo1 | bc`
# Calcula o tempo entre as duas datas.Isso eh a soma do tempo 2 mais
a diferenca entre o tempo 1 - o tempo do ano1 total
diff=`echo $tempodecorrido1 \+ $tempo2 | bc`
if [ $diff = 1440 ] ; then
echo 1 dia
fi
if [ $diff -lt 1440 ] ; then
# Existe menos de 1 dia de diferenca
if [ $diff -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diff
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diff - $horascheias | bc`
if [ $minutos = 0 ] ; then
echo "$horas horas"
else
echo "$horas horas e $minutos minutos"
fi
fi
fi
if [ $diff -gt 1440 ] ; then
# Verifica quantos dias cheios
dias=0
result=$diff
while [ $result -gt 1440 ] || [ $result = 1440 ]
do
result=`echo $result \- 1440 | bc`
dias=`echo $dias \+ 1 | bc`
done
diascheios=`echo $dias \* 1440 | bc`
diffhoras=`echo $diff \- $diascheios | bc` # horas que faltam
serem calculadas
if [ $diffhoras = 0 ] ; then
echo "$dias dias"
fi
if [ $diffhoras -lt 60 ] ; then
# Tem menos de uma hora cheia a diferenca
echo $dias dias e $diffhoras minutos
fi
if [ $diffhoras -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diffhoras
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diffhoras - $horascheias | bc`
if [ $minutos = 0 ] && [ $horas = 0 ] ; then
echo "$dias dias"
fi
if [ $minutos -gt 0 ] && [ $horas = 0 ] ; then
echo "$dias dias e $minutos minutos"
fi
if [ $minutos = 0 ] && [ $horas -gt 0 ] ; then
echo "$dias dias e $horas horas"
fi
if [ $minutos -gt 0 ] && [ $horas -gt 0 ] ; then
echo "$dias dias e $horas horas e $minutos minutos"
fi
fi
fi
else
# A diferenca eh maior que um ano
# Passo 1 - calcula o nro de dias completos entre o periodo, ou seja,
apenas o nro de anos completos
# A resposta eh dada em minutos
anotmp1=`echo $ano1 \+ 1 | bc`
anotmp2=`echo $ano2 \- 1 | bc`
# O seq percorre o periodo. Se ambos forem iguais, ele so processa uma vez
acumuladoano=0
for ano in `seq $anotmp1 $anotmp2`
do
# verifica se o ano da data1 eh bisexto. Calcula o nro. de minutos do ano
cal 2 $ano | grep 29 > /dev/null
resposta=`echo $?`
if [ $resposta = 0 ] ; then
#bisexto=sim
totalano=`echo 366 \* 24 \* 60 | bc`
acumuladoano=`echo $acumuladoano \+ $totalano | bc`
else
#bisexto=nao
totalano=`echo 365 \* 24 \* 60 | bc`
acumuladoano=`echo $acumuladoano \+ $totalano | bc`
fi
done
# Passo 2 - Calcula o total de minutos decorridos desde o fim do tempo1
no ano1 ate o tempo 2 do ano2
cal 2 $ano1 | grep 29 > /dev/null
resposta=`echo $?`
if [ $resposta = 0 ] ; then
#bisexto=sim
totalano=`echo 366 \* 24 \* 60 | bc`
else
#bisexto=nao
totalano=`echo 365 \* 24 \* 60 | bc`
fi
decorrido1=`echo $totalano \- $tempo1 | bc`
# Passo 3 - Faz o cumulativo do periodo
diff=`echo $acumuladoano \+ $decorrido1 \+ $tempo2 | bc`
# Passo 4 - Calcula o nro de dias do periodo
# Faz o calculo contanto o nro de anos tb
# Passo 4.1 - Calcula se a diferenca deu 1 ano completo
# Converte a diferenca para anos
nro_min_ano=525600 # Nros minutos em um ano com 365 dias
anos=0
result=$diff
#if [ $diff -gt $nro_min_ano ] ; then
while [ $result -gt $nro_min_ano ] || [ $result = $nro_min_ano ]
do
anos=`echo $anos \+ 1 |bc`
result=`echo $result \- $nro_min_ano | bc`
done
diff=$result
if [ $diff = 1440 ] ; then
echo $anos anos e 1 dia
fi
if [ $diff -lt 1440 ] ; then
# Existe menos de 1 dia de diferenca
if [ $diff -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diff
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diff - $horascheias | bc`
if [ $minutos = 0 ] ; then
echo "$anos anos e $horas horas"
else
echo "$anos anos e $horas horas e $minutos minutos"
fi
fi
fi
if [ $diff -gt 1440 ] ; then
# Verifica quantos dias cheios
dias=0
result=$diff
while [ $result -gt 1440 ] || [ $result = 1440 ]
do
result=`echo $result \- 1440 | bc`
dias=`echo $dias \+ 1 | bc`
done
diascheios=`echo $dias \* 1440 | bc`
diffhoras=`echo $diff \- $diascheios | bc` # horas que faltam
serem calculadas
if [ $diffhoras = 0 ] ; then
echo "$anos anos e $dias dias."
fi
if [ $diffhoras -lt 60 ] ; then
# Tem menos de uma hora cheia a diferenca
echo $anos anos $dias dias e $diffhoras minutos
fi
if [ $diffhoras -gt 60 ] ; then
# Mais de uma hora de diferenca. Converte para hora
horas=0
result=$diffhoras
while [ $result -gt 60 ] || [ $result = 60 ]
do
result=`echo $result \- 60|bc`
horas=`echo $horas \+ 1|bc`
done
horascheias=`echo $horas \* 60 | bc`
minutos=`echo $diffhoras - $horascheias | bc`
if [ $minutos = 0 ] && [ $horas = 0 ] ; then
echo "$anos anos e $dias dias"
fi
if [ $minutos -gt 0 ] && [ $horas = 0 ] ; then
echo "$anos anos e $dias dias e $minutos minutos"
fi
if [ $minutos = 0 ] && [ $horas -gt 0 ] ; then
echo "$anos anos e $dias dias e $horas horas"
fi
if [ $minutos -gt 0 ] && [ $horas -gt 0 ] ; then
echo "$anos anos e $dias dias e $horas horas e $minutos
minutos"
fi
fi
fi
fi
}
# Essa funcao testa os valoes passados para ver se estao OK.
testa_consistencia()
{
# teste 1
# Verifica se a data 2 eh maior que a data1. Ate pode se igual, mas nao
menor.
# Obrigatoriamente, a data 2 deve ser maior que a data 1. Caso nao seja,
nao calcula
dia1=`echo $1 | cut -c1,2`
mes1=`echo $1 | cut -c3,4`
ano1=`echo $1 | cut -c5-8`
hora1=`echo $1 | cut -c9,10`
minuto1=`echo $1 | cut -c11,12`
dia2=`echo $2 | cut -c1,2`
mes2=`echo $2 | cut -c3,4`
ano2=`echo $2 | cut -c5-8`
hora2=`echo $2 | cut -c9,10`
minuto2=`echo $2 | cut -c11,12`
# Faz a consistencia para ver se as datas informadas estao Ok
if [ $ano1 -gt $ano2 ] ; then # Ano 1 nao pode ser maior que ano 2
echo "O primeiro parametro sempre deve ser de uma data menor que
o segundo."
echo "Saindo do script"
exit
fi
if [ $ano1 = $ano2 ] && [ $mes1 -gt $mes2 ] ; then
# Se eh o mesmo ano, o mes 2 nao pode ser menor que mes 1
echo "O primeiro parametro sempre deve ser de uma data menor que
o segundo."
echo "Saindo do script"
exit
fi
if [ $ano1 = $ano2 ] && [ $mes1 = $mes2 ] ; then
if [ $dia1 -gt $dia2 ] ; then
# Se o ano e mes sao o mesmo, o dia1 nao pode ser maior que o dia2
echo "O primeiro parametro sempre deve ser de uma data menor
que o segundo."
echo "Saindo do script"
exit
fi
fi
if [ $ano1 = $ano2 ] && [ $mes1 = $mes2 ] && [ $dia1 = $dia2 ] ; then
if [ $hora1 -gt $hora2 ] ; then
# Se o ano,mes e dia sao o mesmo, a hora1 nao pode ser maior
que a hora2
echo "O primeiro parametro sempre deve ser de uma data menor
que o segundo."
echo "Saindo do script"
exit
fi
fi
if [ $ano1 = $ano2 ] && [ $mes1 = $mes2 ] && [ $dia1 = $dia2 ] && [
$hora1 = $hora2 ] ; then
if [ $minuto1 -gt $minuto2 ] ; then
# Se o ano,mes,dia e hora sao o mesmo,o minuto1 nao pode ser
maior que o minuto2
echo "O primeiro parametro sempre deve ser de uma data menor
que o segundo."
echo "Saindo do script"
exit
fi
fi
# Teste 2
# Verifica se os valores informados para dia, mes, hora e minuto estao Ok
# Executa varios testes para ver se a data foi passada correta
for data in "$1" "$2"
do
# Testa se o nro de valores passados esta correto
tamanhotmp=`echo $data | wc -c`
tamanho=`echo $tamanhotmp \- 1 | bc`
if [ $tamanho != 12 ] ; then
echo "O Formato da data esta errado. Deve ser informado no seguinte
formado: DDMMAAAAhhmm"
echo "Data informada errada: $data"
echo "Saindo do script"
exit
fi
line=$data
dia=`echo $line | cut -c1,2`
mes=`echo $line | cut -c3,4`
hora=`echo $line | cut -c9,10`
minuto=`echo $line | cut -c11,12`
if [ $minuto -gt 59 ] ; then
echo "A data passada, $data, esta errada."
echo "O numero de minutos nao pode ser superior a 59 min."
echo "Saindo do script."
exit
fi
if [ $hora -gt 23 ] ; then
echo "A data passada, $data, esta errada."
echo "A hora passada nao pode ser maior que 23h."
echo "Saindo do script."
exit
fi
if [ $dia = 00 ] ; then
echo "A data passada, $data, esta errada."
echo "O dia nao pode ser zero."
echo "Saindo do script."
exit
fi
if [ $dia -gt 31 ] ; then
echo "A data passada, $data, esta errada."
echo "O dia passado nao pode ser maior que 31."
echo "Saindo do script."
exit
fi
if [ $mes = 00 ] ; then
echo "A data passada, $data, esta errada."
echo "O mes passado nao pode ser zero."
echo "Saindo do script."
exit
fi
if [ $mes -gt 12 ] ; then
echo "A data passada, $data, esta errada."
echo "O mes passado nao pode ser maior que 12."
echo "Saindo do script."
exit
fi
# Testa , caso o mes seja fevereiro e o dia 29, se o ano eh bisexto
if [ $dia = 29 ] && [ $mes = 02 ] ; then
ano=`echo $data | cut -c5-8`
cal 2 $ano | grep 29 > /dev/null
resposta=`echo $?`
if [ $resposta != 0 ] ; then
# bisexto=nao
echo "A data passada, $data, esta errada."
echo "O ano de $ano nao era bisexto."
echo "Saindo do script."
exit
fi
fi
done
}
# Inicio do shell
# Antes de mais nada, verifica se foi passado no minimo 2 datas como
parametros
if [ "$1" = "" ] || [ "$2" = "" ] ; then
echo "Erro no numero de parametros passados."
echo "Utilize da seguinte forma esse script:
./calc_date.sh <data1> <data2>"
exit
fi
# testa se o formato de data passado esta OK
testa_consistencia "$1" "$2"
# Le a data e carrega ela
line=$1
dia1=`echo $line | cut -c1,2`
mes1=`echo $line | cut -c3,4`
ano1=`echo $line | cut -c5-8`
hora1=`echo $line | cut -c9,10`
minuto1=`echo $line | cut -c11,12`
# Le a data do arquivo2
line2=$2
dia2=`echo $line2 | cut -c1,2`
mes2=`echo $line2 | cut -c3,4`
ano2=`echo $line2 | cut -c5-8`
hora2=`echo $line2 | cut -c9,10`
minuto2=`echo $line2 | cut -c11,12`
if [ $ano1 = $ano2 ] ; then
# O ano eh mesmo
if [ $mes1 = $mes2 ]; then
# O mesmo eh o mesmo
if [ $dia1 = $dia2 ] ; then
# O dia eh o mesmo
if [ $hora1 = $hora2 ] ; then
# Hora igual. Calcula a diferenca em minutos
if [ $minuto1 = $minuto2 ] ; then
# Ambas as datas sao iguais
echo "Nao ha diferenca de data/hora"
else
# Ha diferenca de minutos
diferenca=`echo $minuto2 \- $minuto1 |bc`
echo $diferenca minutos
fi # fecha difenreca minutos
else
# Hora difere. Calcula a diferenca de horas e minutos
converte 0 $hora1 $minuto1
convertido1=`cat tmpmin`
rm tmpmin
converte 0 $hora2 $minuto2
convertido2=`cat tmpmin`
rm tmpmin
difmin $convertido1 $convertido2
fi # Fecha diferenca horas/minutos
else
# Existe diferenca de dias
converte 0 $hora1 $minuto1 $dia1
convertido1=`cat tmpmin`
rm tmpmin
converte 0 $hora2 $minuto2 $dia2
convertido2=`cat tmpmin`
rm tmpmin
difmin $convertido1 $convertido2
fi # Fecha diferenca dias/horas/minutos
else
# Os meses nao sao iguais
converte 0 $hora1 $minuto1 $dia1 $mes1 $ano1
convertido1=`cat tmpmin`
rm tmpmin
converte 0 $hora2 $minuto2 $dia2 $mes2 $ano2
convertido2=`cat tmpmin`
rm tmpmin
difmin $convertido1 $convertido2
fi # Fecha diferenca mes/dias/horas/minutos
else
# O ano eh diferente
converte 0 $hora1 $minuto1 $dia1 $mes1 $ano1
convertido1=`cat tmpmin`
rm tmpmin
converte 0 $hora2 $minuto2 $dia2 $mes2 $ano2
convertido2=`cat tmpmin`
rm tmpmin
difmin2 $convertido1 $convertido2 $ano1 $ano2
fi # Fecha diferenca anos/mes/dias/horas/minutos
#
# Fim do script
#