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

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

Re: [shell-script] Manipular tempo em shell script


From: Fabricio Lopes de Souza
Subject: Re: [shell-script] Manipular tempo em shell script
Date: Thu, 2 Mar 2006 13:04:02 +0000

Priscila , demorou um pouco para ficar pronto mas tah ae , dei uma
atualizada no script que agora conta com essa função . Qualquer
sugestão é bem vinda .

###########################################################
#!/bin/bash
# Fabricio Lopes de Souza
# address@hidden / address@hidden
# Facilita trabalhar datas
# Em desenvolvimento
# Ultima atualizacao : 02/03/2006
# Funcoes Prontas :
# usage - Usage
# check - Verifica se o ano eh bissexto e se o dia tem 30/31 dias
[29/28 para fev]
# error - Trata alguns erros
# set_date - Verifica se a sintaxe da data esta correta , e divide .
# add_[year/month/day/hour/minutes/seconds] - Adiciona $1
[year/month/day/hour/minutes/seconds]
# del_[year/month/day/hour/minutes/seconds] - Remove $1
[year/month/day/hour/minutes/seconds]
# compara - calcula o intervalo entre o horario de entrada com o horario atual

usage() {
        echo "Uso :"
        echo "
        $0 [-/+]M MES - subtrai/soma [MESES] a data atual
        $0 [-/+]d DIA - subtrai/soma [DIAS] a data atual
        $0 [-/+]H HORA - subtrai/soma [HORAS] a data atual
        $0 [-/+]m MINUTOS - subtrai/soma [MINUTOS] a data atual
        $0 [-/+]s SEGUNDOS - subtrai/soma [SEGUNDOS] a data atual
        $0 [-/+]T TIME - subtrai/soma [HH:MM:SS] a data atual
        $0 [-/+]D DATA [DD/MM/YYYY HH:MM:SS] - Usa DATA ao inves da data atual
        $0 HH:MM:SS - Diferenca da hora atual - HORA
        Obs.: -D pode ser combinado com qualquer opcao anterior

        Nao existe um limite de quantidade para as opcoes
        "
        set_date
        exit
}

# VARIAVEIS #
RE_YEAR="(19|2[01])([02468][048]|[13579][26])"


set_date() {
# Separa DD/MM/YYY HH:MM:SS em variaveis proprias
YEAR=$(echo ${DATE} | cut -d" " -f1 | cut -d"/" -f3)
MONTH=$(echo ${DATE} | cut -d" " -f1 | cut -d"/" -f2)
DAY=$(echo ${DATE} | cut -d" " -f1 | cut -d"/" -f1)
HOUR=$(echo ${DATE} | cut -d" " -f2 | cut -d":" -f1)
MINUTES=$(echo ${DATE} | cut -d" " -f2 | cut -d":" -f2)
SECONDS=$(echo ${DATE} | cut -d" " -f2 | cut -d":" -f3)

# Remove  o zero da frente de numeros menores que 10
# para nao dar problema na hora de compara-los
DAY=$(echo ${DAY} | sed "s/^0\([0-9]\)/\1/")
MONTH=$(echo ${MONTH} | sed "s/^0\([0-9]\)/\1/")
HOUR=$(echo ${HOUR} | sed "s/^0\([0-9]\)/\1/")
MINUTES=$(echo ${MINUTES} | sed "s/^0\([0-9]\)/\1/")
SECONDS=$(echo ${SECONDS} | sed "s/^0\([0-9]\)/\1/")

# Checa se a data eh coerente , uma checagem bem simples
[[ ${YEAR} -gt 2100 ]] || [[ ${YEAR} -lt 1900 ]] && error 2
[[ ${MONTH} -gt 12 ]] || [[ ${MONTH} -lt 0 ]] && error 2
[[ ${DAY} -gt 31 ]] || [[ ${DAY} -lt 0 ]] && error 2
[[ ${HOUR} -gt 24 ]] || [[ ${YEAR} -lt 0 ]] && error 2
[[ ${MINUTES} -gt 60 ]] || [[ ${MINUTES} -lt 0 ]] && error 2
[[ ${SECONDS} -gt 60 ]] || [[ ${SECONDS} -lt 0 ]] && error 2


}
# O check eh necessario quando adicionamos/removemos meses , pois o
numero maximo de dias
# que cada mes pode ter eh diferente
check() {

        # Checa se o ano eh bissexto , caso seja , fevereiro vai ter 29 dias :)
        # RE tirada da lista de shell by hardcorepunkfx <s3 <at>
blackcodemail.com>
        echo ${YEAR} | egrep "${RE_YEAR}" 1>/dev/null && FEV=29 || FEV=28
        # Que mes estamos ?
        case ${MONTH} in
                01|03|05|07|08|10|12|1|3|5|7|8) MAX_DAY=31 ;;
                02|2) MAX_DAY=${FEV} ;;
                *) MAX_DAY=30 ;;
        esac
}
# Simples tratacao de erros
error() {
        case $1 in
                1) erro="Opcao Invalida" ;;
                2) erro="Data Invalida" ;;
                3) erro="-D necessita de mais uma opcao" ;;
                *) erro="Erro Indefinido" ;;
        esac
        echo "!! ERRO - ${erro} "
        exit $1
}

add_year() {
                ADD_YEAR=$1
                # Sem problemas , somar anos eh soh ... somar! =D
                YEAR=$( expr ${YEAR} + ${ADD_YEAR} )
                # Porem temos que ver se agora nosso ano eh bissexto
                check
}
add_month() {
                ADD_MONTH=$1
                MONTH=$(expr ${MONTH} + ${ADD_MONTH})
                while [[ ${MONTH} -gt 12 ]] ; do
                        add_year 1
                        # Maximo de meses sempre eh 12
                        MONTH=$( expr ${MONTH} - 12 )
                done
                check
}
add_day() {
                # MAX_DAY ?
                check
                ADD_DAY=$1
                DAY=$(expr ${DAY} + ${ADD_DAY} )
                # Caso nosso DAY agora tenha mais que o MAX_DAY
permitido , necessitanos adicionar 1 mes
                # Essa logica serve para [quase] todos add/del .
                while [[ ${DAY} -gt ${MAX_DAY} ]] ; do
                        # Adicionamos 1 mes , entao removemos o que sobrou
                        DAY=$(expr ${DAY} - ${MAX_DAY})
                        add_month 1
                done
}
add_hour() {
                ADD_HOUR=$1
                HOUR=$( expr ${HOUR} + ${ADD_HOUR} )
                # Na nossa [ou do mundo todo sei la XD] notacao , nao
existe hora = 24 , mas existe hora = 00
                while [[ ${HOUR} -ge 24 ]] ; do
                        add_day 1
                        HOUR=$( expr ${HOUR} - 24 )
                done
}
add_minutes() {
                ADD_MINUTES=$1
                MINUTES=$( expr ${MINUTES} + ${ADD_MINUTES} )
                # Mesma coisa , nao existe minuto 60 , e sim 00
                while [[ ${MINUTES} -ge 60 ]] ; do
                        add_hour 1
                        MINUTES=$(expr ${MINUTES} - 60)
                done
}
add_seconds() {
      ADD_SECONDS=$1
      SECONDS=$( expr ${SECONDS} + ${ADD_SECONDS} )
                # Mesma coisa 8-)
           while [[ ${SECONDS} -ge 60 ]] ; do
                add_hour 1
        SECONDS=$(expr ${SECONDS} - 60)
                done
}
add_time() {
# add_time server para passarmos direto uma notacao de tempo completa
para ser somada
# HH:MM:SS , apenas divide e chama cada metodo
        ADD_HOUR=$(echo $1 | cut -d":" -f1)
        ADD_MINUTES=$(echo $1 | cut -d":" -f2)
        ADD_SECONDS=$(echo $1 | cut -d":" -f3)
        add_hour ${ADD_HOURS}
        add_minutes ${ADD_MINUTES}
        add_seconds ${ADD_SECONDS}
}
del_year(){
        DEL_YEAR=$1
        # just it
        YEAR=$( expr ${YEAR} - ${DEL_YEAR} )
        check
}
del_month(){
        DEL_MONTH=$1
        MONTH=$( expr ${MONTH} - ${DEL_MONTH} )
        # Se o mes eh = 0 ou negativo , entao vamos voltar 1 ano
        while [[ ${MONTH} -le 0 ]] ; do
                del_year 1
                # se ele eh negativo , transformamos em positivo
                MONTH=$( expr 0 - ${MONTH})
                # partimos do fim [12] - nosso mes , que era negativo
, e temos nosso mes atual
                MONTH=$( expr 12 - ${MONTH})
        done
}
del_day(){
        DEL_DAY=$1
        DAY=$( expr ${DAY} - ${DEL_DAY} )
        while [[ ${DAY} -le 0 ]] ; do
                del_month 1
                # A jogada esta aqui , se nosso dia eh = 0 , entao ele
eh o ultimo dia do mes anterior
                if [[ ${DAY} -eq 0 ]] ; then
                        del_month 1
                        check
                        DAY=${MAX_DAY}
                fi
        done
}
del_hour(){
        DEL_HOUR=$1
        HOUR=$( expr ${HOUR} - ${DEL_HOUR} )
        # padrao ...
        while [[ ${HOUR} -lt 0 ]] ; do
                del_day 1
                HOUR=$( expr 0 - ${HOUR})
                HOUR=$( expr 24 - ${HOUR})
        done
}
del_minutes(){
        DEL_MINUTES=$1
        MINUTES=$( expr ${MINUTES} - ${DEL_MINUTES} )
        # padrao ...
        while [[ ${MINUTES} -lt 0 ]] ; do
                del_hour 1
                MINUTES=$( expr 0 - ${MINUTES} )
                MINUTES=$( expr 60 - ${MINUTES} )
        done
}
del_seconds(){
        DEL_SECONDS=$1
        SECONDS=$( expr ${SECONDS} - ${DEL_SECONDS} )
        # padrao 8-)
        while [[ ${SECONDS} -lt 0 ]] ; do
                del_hour 1
                SECONDS=$( expr 0 - ${SECONDS} )
                SECONDS=$( expr 60 - ${SECONDS} )
        done
}
compara() {
        HOUR_1=$(echo $1 | cut -d":" -f1)
        MINUTES_1=$(echo $1 | cut -d":" -f2)
        SECONDS_1=$(echo $1 | cut -d":" -f3)
        TIME_SEC=$( expr $(expr $HOUR_1 \* 3600) + $( expr $MINUTES_1
\* 60 ) + $SECONDS_1 )
        TIME_SEC_2=$( expr $(expr $HOUR \* 3600) + $( expr $MINUTES \*
60 ) + $SECONDS )
        FINAL_TIME=$( expr $TIME_SEC - $TIME_SEC_2 )
        [[ $FINAL_TIME -lt 0 ]] && FINAL_TIME=$( expr 0 - $FINAL_TIME )
        FINAL_HOUR=$( expr $FINAL_TIME / 3600 )
        TMP=$( expr $FINAL_TIME % 3600 )
        FINAL_MINUTES=$( expr $TMP / 60 )
        FINAL_SECONDS=$( expr $TMP % 60 )

        echo $( echo ${DATE}| cut -d" " -f 2)
        echo "-"
        echo $HOUR_1:$MINUTES_1:$SECONDS_1
        echo "="
   printf "%2.2d:%2.2d:%2.2d\n" $FINAL_HOUR $FINAL_MINUTES $FINAL_SECONDS
}

del_time() {
        # mesma coisa do add_time XD
        DEL_HOUR=$(echo $1 | cut -d":" -f1)
        DEL_MINUTES=$(echo $1 | cut -d":" -f2)
        DEL_SECONDS=$(echo $1 | cut -d":" -f3)
        del_hour ${DEL_HOUR}
        del_minutes ${DEL_MINUTES}
        del_seconds ${DEL_SECONDS}
}
main() {

# Caso seja usado a opcao -D , entao nossa data de referencia nao eh a
data atual
if [[ $1 = -D ]] ; then
        [[ $# -lt 5 ]] && error 3
        # Date vira nossa data
        DATE="$2 $3"
        shift 3
else
        # Date eh agora
        DATE=$(date +%d/%m/%Y" "%H:%M:%S)
fi

# checa a data e faz a separacao
set_date

# sem argumentos = usage
[[ $# -eq 0 ]] && usage

# Outra boa jogada , while infinito ; possibilita o uso de infinitos argumentos
# exemplo : date_util -H 1 -H 2 -Y 1 -M 1 -H 3 +T 10:10:10
while : ; do
        # Cada parametro chama a funcao correta
        case $1 in
                +Y) add_year $2 ;;
                -Y) del_year $2 ;;
                +d) add_day $2 ;;
                -d) del_day $2 ;;
                +M) add_month $2 ;;
                -M) del_month $2 ;;
                +H) add_hour $2 ;;
                -H) del_hour $2 ;;
                +m) add_minutes $2 ;;
                -m) del_minutes $2 ;;
                +s|+S) add_seconds $2 ;;
                -s|-S) del_seconds $2 ;;
                +T) add_time $2 ;;
                -T) del_time $2 ;;
                [0-9]*) compara $1 ; exit 0 ;;
                "") return ;;
                *) error 1 ;;
        esac
        # Limpa $1 e $2 para chamar os proximos parametros
        shift 2


done


}

main $*

# Saida :)
echo old : ${DATE}
printf "%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d\" $DAY $MONTH $YEAR $HOUR
$MINUTES $SECONDS
###########################################################################

On 2/15/06, Fabricio Lopes de Souza <address@hidden> wrote:
> Priscila ,
>
> Como disse no topico que postei um script que manipulava datas ,
> aceito sugestoes , vou tomar esse post como uma sugestao e vou tentar
> fazer a implementacao para agregar ao meu script
>
> abraços :)
> [quote]
> Algém sabe se é possível manipular horas (somar,subtrair) usando o
> comando date ou algum atifício em shell script?
>
> Exemplo:
>
> Ver quantas horas e minutos faltam da hora atual $(date +%H:%M) até as
> 18:45 (no formato %H:%M necessariamente).
>
> Estou escrevendo um script e é a única coisa que não consegui
> implementar (já procurei no google) .
>
> Obrigada, Priscila.
> [/qoute]
>


reply via email to

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