My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# ----------------------------------------------------------------------------
# Faz cálculos com horários.
# A opção -r torna o cálculo relativo à primeira data, por exemplo:
# 02:00 - 03:30 = -01:30 (sem -r) e 22:30 (com -r)
#
# Uso: zzhora [-r] hh:mm [+|- hh:mm]
# Ex.: zzhora 8:30 + 17:25 # preciso somar dois horários!
# zzhora 12:00 - agora # quando falta para o almoço?
# zzhora -12:00 + -5:00 # horas negativas!
# zzhora 1000 # quanto é 1000 minutos?
# zzhora -r 5:30 - 8:00 # que horas ir dormir para acordar às 5:30?
# zzhora -r agora + 57:00 # e daqui 57 horas, será quando?
#
# Autor: Aurelio Marinho Jargas, www.aurelio.net
# Desde: 2000-02-22
# Versão: 2
# Licença: GPL
# ----------------------------------------------------------------------------
zzhora ()
{
zzzz -h hora "$1" && return

local hhmm1 hhmm2 operacao hhmm1_orig hhmm2_orig
local hh1 mm1 hh2 mm2 n1 n2 resultado negativo
local horas minutos dias horas_do_dia hh mm hh_dia extra
local relativo=0

# Opções de linha de comando
if [ "$1" = '-r' ]
then
relativo=1
shift
fi

# Verificação dos parâmetros
[ "$1" ] || { zztool uso hora; return 1; }

# Dados informados pelo usuário (com valores padrão)
hhmm1="$1"
operacao="${2:-+}"
hhmm2="${3:-0}"
hhmm1_orig="$hhmm1"
hhmm2_orig="$hhmm2"

# Somente adição e subtração são permitidas
if test "$operacao" != '-' -a "$operacao" != '+'
then
echo "Operação inválida '$operacao'. Deve ser + ou -."
return 1
fi

# Atalhos bacanas para a hora atual
[ "$hhmm1" = 'agora' -o "$hhmm1" = 'now' ] && hhmm1=$(date +%H:%M)
[ "$hhmm2" = 'agora' -o "$hhmm2" = 'now' ] && hhmm2=$(date +%H:%M)

# Se as horas não foram informadas, coloca zero
[ "${hhmm1#*:}" = "$hhmm1" ] && hhmm1="0:$hhmm1"
[ "${hhmm2#*:}" = "$hhmm2" ] && hhmm2="0:$hhmm2"

# Extrai horas e minutos para variáveis separadas
hh1="${hhmm1%:*}"
mm1="${hhmm1#*:}"
hh2="${hhmm2%:*}"
mm2="${hhmm2#*:}"

# Retira o zero das horas e minutos menores que 10
hh1="${hh1#0}"
mm1="${mm1#0}"
hh2="${hh2#0}"
mm2="${mm2#0}"

# Se tiver algo faltando, salva como zero
hh1="${hh1:-0}"
mm1="${mm1:-0}"
hh2="${hh2:-0}"
mm2="${mm2:-0}"

# Validação dos dados
if ! (zztool testa_numero_sinal "$hh1" && zztool testa_numero_sinal "$mm1")
then
echo "Horário inválido '$hhmm1_orig', deve ser HH:MM"
return 1
fi
if ! (zztool testa_numero_sinal "$hh2" && zztool testa_numero_sinal "$mm2")
then
echo "Horário inválido '$hhmm2_orig', deve ser HH:MM"
return 1
fi

# Os cálculos são feitos utilizando apenas minutos.
# Então é preciso converter as horas:minutos para somente minutos.
n1=$((hh1*60+mm1))
n2=$((hh2*60+mm2))

# Tudo certo, hora de fazer o cálculo
resultado=$(($n1 $operacao $n2))

# Resultado negativo, seta a flag e remove o sinal de menos "-"
if [ $resultado -lt 0 ]
then
negativo='-'
resultado="${resultado#-}"
fi

# Agora é preciso converter o resultado para o formato hh:mm

horas=$((resultado/60))
minutos=$((resultado%60))
dias=$((horas/24))
horas_do_dia=$((horas%24))

# Restaura o zero dos minutos/horas menores que 10
hh="$horas"
mm="$minutos"
hh_dia="$horas_do_dia"
[ $hh -le 9 ] && hh="0$hh"
[ $mm -le 9 ] && mm="0$mm"
[ $hh_dia -le 9 ] && hh_dia="0$hh_dia"

#TODO: usar um exemplo com horas negativas
# Decide como mostrar o resultado para o usuário.
#
# Relativo:
# $ zzhora -r 10:00 + 48:00
# 10:00 (2 dias)
#
# Normal:
# $ zzhora 10:00 + 48:00
# 58:00 (2d 10h 0m)
#
if [ $relativo -eq 1 ]
then

# Relativo

# Somente em resultados negativos o relativo é útil.
# Para valores positivos não é preciso fazer nada.
if [ "$negativo" ]
then
# Para o resultado negativo é preciso refazer algumas contas
minutos=$(( (60-minutos) % 60))
dias=$((horas/24 + (minutos>0) ))
hh_dia=$(( (24 - horas_do_dia - (minutos>0)) % 24))
mm="$minutos"

# Zeros para dias e minutos menores que 10
[ $mm -le 9 ] && mm="0$mm"
[ $hh_dia -le 9 ] && hh_dia="0$hh_dia"
fi

# "Hoje", "amanhã" e "ontem" são simpáticos no resultado
case $negativo$dias in
1)
extra='amanhã'
;;
-1)
extra='ontem'
;;
0|-0)
extra='hoje'
;;
*)
extra="$negativo$dias dias"
;;
esac

echo "$hh_dia:$mm ($extra)"
else

# Normal

echo "$negativo$hh:$mm (${dias}d ${horas_do_dia}h ${minutos}m)"
fi
}

Change log

r710 by aureliojargas on Mar 29, 2012   Diff
SEGURANÇA: $1 colocado entre aspas na
chamada padrão zzzz -h de todas as
funções.
Go to: 
Sign in to write a code review

Older revisions

r679 by aureliojargas on Mar 28, 2012   Diff
zzhora: validação dos dados para maior
segurança.
r678 by aureliojargas on Mar 28, 2012   Diff
zzhora: Melhorada mensagem de erro
(agora segue padrão da zzdata),
colocadas aspas ao redor das variáveis
para aumentar a segurança.
r668 by aureliojargas on Mar 28, 2012   Diff
lint: removendo espaços inúteis.
All revisions of this file

File info

Size: 4431 bytes, 174 lines
Powered by Google Project Hosting