shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Diferença entre duas Datas


From: Jose Edson Moreno Jr
Subject: Re: [shell-script] Diferença entre duas Datas
Date: Tue, 8 Feb 2011 00:11:31 -0200

Oi ,

  Bom quando vamos mexer com datas temos que ter bem claro o que desejamos
manipular, pois senão cometemos erros:

Primeira coisa:
   No intervalo de datas entre 20100127 à 20101210 , temos na verdade 317
dias a saber :

de 27/01/2010  31/01/2010 - 4 dias
02/2010 - 28 dias
03/2010 - 31 dias
04/2010 - 30 dias
05/2010 - 31 dias
06/2010 - 30 dias
07/2010 - 31 dias
08/2010 - 31 dias
09/2010 - 30 dias
10/2010 - 31 dias
11/2010 - 30 dias
01/12/2010 `a 10/12/2010 - 10 dias
Total = 317 dias

Bom, se deseja algo direto em shell e utilizando o que vem em linux, pode
-se se utilizar o seguinte script:

#!/bin/bash
data_inicial=$1
data_final=$2
# Extrai as datas da entrada usando o date, assim não me preocupo com
formatacao de entrada, desde que seja data, o date trata
ano_inicial=$(date --date "${data_inicial}" +"%Y")
mes_inicial=$(date --date "${data_inicial}" +"%m")
dia_inicial=$(date --date "${data_inicial}" +"%d")
ano_final=$(date --date "${data_final}" +"%Y")
mes_final=$(date --date "${data_final}" +"%m")
dia_final=$(date --date "${data_final}" +"%d")
# Verifico se o intervalo esta no mesmo ano
if [ ${ano_inicial} -ne ${ano_final} ]; then
        # Caso nao esteja, vejo o numero de dias ate o final do ano inicial
        total_dias=$(date --date "${ano_inicial}0101 + $(($(date
--date="${ano_inicial}1231" +%s) - $(date
--date="${ano_inicial}${mes_inicial}${dia_inicial}" +%s) - 86399)) sec"
+"%j")
        cont_ano=0
         # Aqui e o pulo de gato para o date tratar diferencas maiores que
365 dias, faco um loop para contar os dias dos anos
        while [ $((ano_final - ano_inicial - cont_ano)) -ne 0 ]; do
                cont_ano=$((cont_ano + 1))
                # Verifico se a diferenca de anos e maior que 1
                if [ ${ano_final} -eq  $((ano_inicial + cont_ano)) ]; then
                        # Sendo menor simplesmente calculo o total de dias
do ano seguinte e somo ao inicio
                        total_dias=$((total_dias + $(date --date
"${ano_final}0101  + $(($(date --date="${ano_final}${mes_final}${dia_final}"
+%s) - $(date --date="${ano_final}0101" +%s) )) sec" +"%j" )))
                else
                       # Sendo maior que 1 ano, pego o numero de dias do ano
e acumulo
                        total_dias=$((total_dias + $(date --date
"$((ano_inicial + cont_ano))0101  + $(($(date --date="$((ano_inicial +
cont_ano))1231" +%s) - $(date --date="$((ano_inicial + cont_ano))0101" +%s)
)) sec" +"%j" )))
                fi
        done
else
        # Faco o calculo de dias no ano
        total_dias=$(date --date "${ano_inicial}0101 + $(($(date
--date="${ano_final}${mes_final}${dia_final}" +%s) - $(date
--date="${ano_inicial}${mes_inicial}${dia_inicial}" +%s) - 86399)) sec"
+"%j")
fi
echo "${total_dias} dias corridos"


Alguns detalhes a respeito deste calculo :

1 - O comando date faz contas somente com numero serial de segundos a partir
de 01/01/1970 ,  portanto este script somente funciona para datas a partir
desta data
2 - Este tipo de calculo somente obtem o numero total de dias corridos em um
ano, ou seja no maximo 365 dias ou 366 dias para anos bisextos, para
trabalhar com intervalos maiores, temos que adptar
3 - Toda vez que mexemos com numeros serias de segundos, temos que adequa-lo
ao ano em questão, por este motivos há calculos de diferenças nos dates,
somente para obter o numero real de segundos naquele ano

Pessoal, este é um script testado em bash no linux ( bash versão
4.1.5(1)-release e date (GNU coreutils) 8.5 ) , para outros sistemas e
shell, adequa-lo a situação. Somente estou demonstrando uma maneira de fazer
isso em shell com recursos gnu, vendo que houve dificuldades a respeito
disto, há meios mais simples de se fazer isso utilizando-se de outras
linguagens ..

Boa sorte pessoal !

Em 5 de fevereiro de 2011 13:47, fsilva6 <address@hidden> escreveu:

>
>
> Estou montando um script que traz com resultado o total de dias entre duas
> datas.
>
> date1=20101210
> date2=20100127
>
> echo $date1 $date2 | awk '{
>
> #parse
> yearStar=substr($1,1,4);
> mothStar=substr($1,5,2);
> dayStar=substr($1,7,2);
>
> yearEnd=substr($2,1,4);
> monthEnd=substr($2,5,2);
> dayEnd=substr($2,7,2);
>
> #Pegar Segundos
> secs1=((yearStar - 1970)*365.25+(mothStar*30.5)+dayStar)*24*60*60;
> secs2=((yearEnd - 1970)*365.25+(monthEnd*30.5)+dayEnd)*24*60*60;
>
> #Subtracao
> diffSecs=secs1 - secs2;
>
> #Segundos Para Dia
> print diffSecs/86400;
> }'
>
> Como Resultado estou obtendo o valor 318.5 .
> Só que valor correto deveria ser 316.
>
> Alguém pode me ajudar a identificar onde estou errando...Vale lembrar que
> estou usando o AIX (AIX XXXXX 3 5 0023082B4C00 - Release 5300-10).
>
>  
>



-- 
Jose Edson Moreno Jr.


[As partes desta mensagem que não continham texto foram removidas]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]