Com dateutils 's datediff
(não é GNU desculpe), (anteriormente ddiff
, dateutils.ddiff
no Debian):
$ dateutils.ddiff -f '%Y years, %m months, %d days, %H:%0M:%0S' \
'2012-01-23 15:23:01' '2017-06-01 09:24:00'
5 years, 4 months, 8 days, 18:00:59
(datas tomadas como UTC, adicione algo como --from-zone=Europe/London
para as datas a serem tomadas como hora local no fuso horário correspondente. --from-zone=localtime
pode funcionar para o fuso horário padrão no sistema; --from-zone="${TZ#:}"
funcionaria o tempo todo como $TZ
especifica o caminho de um arquivo de fuso horário da IANA (como TZ=:Europe/London
, não TZ=GMT0BST,M3.5.0/1:00:00,M10.5.0/2:00:00
especificação TZ no estilo POSIX)).
Com ast-aberto date
, então ainda não com ferramentas GNU desculpe (se estiver usando ksh93
como seu shell, que date
pode estar disponível como um builtin) você pode usar date -E
para obter a diferença entre duas datas em um formato que dê 2 números com unidades:
$ date -E 1970-01-01 2017-06-01
47Y04M
$ date -E 2017-01-01 2017-06-01
4M29d
$ date -E 12:12:01 23:01:43
10h49m
Observe que qualquer coisa acima de hora é ambígua, pois os dias têm um número variável de horas em locais com horário de verão (23, 24 ou 25) e meses e anos têm um número variável de dias. pode não fazer muito sentido ter mais precisão do que essas duas unidades acima.
Por exemplo, há exatamente um ano entre 2015-01-01 00:00:00 e 2016-01-01 00:00:00 ou entre 2016-01-01 00:00:00 e 2017-01- 01 00:00:00, mas essa não é a mesma duração (365 * 24 horas em um caso, 366 * 24 horas no outro)
Há exatamente um dia entre 2017-03-24 12:00:00 e 2017-03-25 12:00:00 ou entre 2017-03-25 12:00:00 e 2017-03-26 12:00 : 00, mas quando esses são hora local em países europeus (que mudaram para o horário de verão em 2017-03-26), que um dia é de 24 horas em um caso e 23 horas no outro. / p>
Em outras palavras, uma duração que mencione anos, meses, semanas ou dias é significativa apenas quando associada a um dos limites para os quais ela deve ser aplicada (e ao fuso horário). Assim, você não pode converter um número de segundos para tal duração sem saber a que hora (de ou até) ela deve ser aplicada (a menos que você queira usar definições aproximadas de dia (24 horas), mês (30 * 24 horas) ou ano (365 * 24 horas)).
Até certo ponto, até mesmo uma duração em segundos é ambígua. Para simplificação, os segundos no tempo Unix epoch são definidos como a parte 86400 de um determinado dia da Terra 1 . Esses segundos estão ficando cada vez mais longos à medida que a Terra desce.
Então, algo como (com o GNU date
):
d1='2016-01-01 00:00:00' d2='2017-01-01 00:00:00'
eval "$(date -d "@$(($(date -d "$d2" +%s) - $(date -d "$d1" +%s)))" +'
delta="$((%-Y - 1970)) years, $((%-m - 1)) months, $((%-d - 1)) days, %T"')"
echo "$delta"
Ou em fish
:
date -d@(expr (date -d $d2 +%s) - (date -d $d1 +%s)) +'%Y %-m %-d %T' | \
awk '{printf "%s years, %s months, %s days, %s\n", $1-1970, $2-1, $3-1, $4, $5}'
Geralmente, não daria a você algo correto, pois o tempo delta é aplicado a 1970, em vez da data de início real de 2016.
Por exemplo, acima, isso me dá (em um fuso horário Europa / Londres):
1 years, 0 months, 1 days, 01:00:00
em vez de
1 years, 0 months, 0 days, 00:00:00
(isso ainda pode ser uma boa aproximação para você).
1 Tecnicamente, enquanto um dia tem 86400 segundos de Unix, os sistemas conectados à rede normalmente sincronizam seu relógio com os relógios atômicos usando SI segundos. Quando um relógio atômico diz 12: 00: 00.00, esses sistemas Unix também dizem 12: 00: 00.00. A exceção é apenas na introdução de segundos bissextos, em que ou há um segundo Unix que dura 2 segundos ou alguns segundos que duram um pouco mais para manchar esse segundo extra em um período mais longo.
Assim, é possível saber a duração exata (em termos de segundos atômicos) entre dois timestamps Unix (emitidos por sistemas sincronizados ao relógio atômico): obter a diferença do tempo Unix epoch entre os dois timestamps e adicione o número de segundos que foram adicionados entre eles.
datediff
também tem -f %rS
para obter o número de segundos reais entre duas datas:
$ dateutils.ddiff -f %S '1990-01-01 00:00:00' '2010-01-01 00:00:00' 631152000 $ dateutils.ddiff -f %rS '1990-01-01 00:00:00' '2010-01-01 00:00:00' 631152009
A diferença é para os 9 segundos de salto que foram adicionados entre 1990 e 2010.
Agora, esse número de segundos real não ajudará você a calcular o número de dias, já que os dias não têm um número constante de real segundos. Existem exatamente 20 anos entre essas 2 datas e aqueles 9 saltos segundos, em vez de atrapalhar o caminho para chegar a esse valor. Observe também que ddiff
do %rS
só funciona quando não é combinado com outros especificadores de formato. Além disso, os segundos bissextos futuros não são conhecidos com bastante antecedência, mas também as informações sobre segundos bissextos recentes podem não estar disponíveis. Por exemplo, o meu sistema não sabe quais foram depois de 2012-07-01.