Data usada:
$ dateA="2008-02-04 00:00:00 UTC"
O primeiro motivo para obter datas com horários alterados é solicitar datas "locais":
$ date -d "$dateA"
Sun Feb 3 19:00:00 EST 2008
O que será corrigido se você especificar um horário UTC:
$ TZ=UTC0 date -d "$dateA"
Mon Feb 4 00:00:00 UTC 2008
Ou melhor (crie o hábito de usá-lo) use a opção -u
da data:
$ date -ud "$dateA"
Mon Feb 4 00:00:00 UTC 2008
Um segundo motivo é solicitar "itens relativos" com um sinal:
$ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") +1 year" ### wrong
Tue Feb 3 23:00:00 UTC 2009
$ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") 1 year" ### better
Mon Feb 4 00:00:00 UTC 2008
Mas todos os problemas do tempo (geralmente) desaparecem quando um "fuso horário" (-z) é usado:
$ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") +1 year" ### Best
Wed Feb 4 00:00:00 UTC 2009
$ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") 1 year" ### Preferred
Wed Feb 4 00:00:00 UTC 2009
O problema está relacionado à maneira como uma string de data é analisada, se o valor de TZ estiver ausente, o +1 pode ser interpretado como um valor de fuso horário:
$ date -ud "2008-02-04 00:00:00 +3 year"
Tue Feb 3 21:00:00 UTC 2009
Mesmo que um valor de ambiente para TZ tenha sido definido:
$ TZ=UTC0 date -ud "2008-02-04 00:00:00 +3 year"
Tue Feb 3 21:00:00 UTC 2009
Sim, o ano foi aumentado uma vez (2009 em vez de 2008), mas o +3
foi usado para uma alteração do tempo apresentado (não o pretendido).
Repito: o problema é que +3
pode ser analisado como um valor de fuso horário.
Além disso, para converter (época) segundos em datas, a data GNU pode usar "@"
$ dateAsec="$( date -ud "$dateA" +"%s" )
$ date -ud @"$dateAsec"
Mon Feb 4 00:00:00 UTC 2008
O script (usando uma função (newdate)) pode ser escrito assim:
#!/bin/bash
dateI="$(date -ud "2008-02-04 00:00:00 UTC" +%s)"
dateF="$(date -u +%s)"
newdate(){ date -ud "$(date +"%Y-%m-%d %T %z" -ud @"$dateI") $1 year" +"%s"; }
n=0
while
dateN="$( newdate "$n" )"
(( dateN < dateF ));
do
dateNhuman="$(date +"%Y-%m-%d %T %z" -ud @"$dateN")"
echo "dateN=$dateN --- $dateNhuman ---> $dateF $(( $dateF - $dateN )) $n"
(( n++ ))
done
Resultados:
dateN=1202083200 --- 2008-02-04 00:00:00 +0000 ---> 1470543626 268460426 0
dateN=1233705600 --- 2009-02-04 00:00:00 +0000 ---> 1470543626 236838026 1
dateN=1265241600 --- 2010-02-04 00:00:00 +0000 ---> 1470543626 205302026 2
dateN=1296777600 --- 2011-02-04 00:00:00 +0000 ---> 1470543626 173766026 3
dateN=1328313600 --- 2012-02-04 00:00:00 +0000 ---> 1470543626 142230026 4
dateN=1359936000 --- 2013-02-04 00:00:00 +0000 ---> 1470543626 110607626 5
dateN=1391472000 --- 2014-02-04 00:00:00 +0000 ---> 1470543626 79071626 6
dateN=1423008000 --- 2015-02-04 00:00:00 +0000 ---> 1470543626 47535626 7
dateN=1454544000 --- 2016-02-04 00:00:00 +0000 ---> 1470543626 15999626 8
Todos os anos aparecem e tudo parece correto.