Diferença horária entre duas datas ISO8601 com segunda parte fracionária

0

Eu recebo os seguintes carimbos de tempo do Alpine Linux:

2017-04-25T07:19:53.946109551Z    
2017-04-25T07:19:53.946155414Z

Como decodifico e sei quanto tempo passou entre eles?

A questão relacionada fala sobre o tempo da época, enquanto aqui não é claramente.

    
por Yakov 25.04.2017 / 14:15

1 resposta

5

Em sistemas GNU:

d1=2017-04-25T07:19:53.946109551Z
d2=2017-04-25T07:19:53.946155414Z
printf '%s - %s\n' "$(date -d "$d2" +%s.%N)" "$(date -d "$d1" +%s.%N)" | bc

Daria a você a diferença de tempo como um número de segundos em ponto flutuante.

Ressalva: o número será dado usando o período ( . ) como o separador decimal, mesmo em locais onde a vírgula ( , ) é usada.

Você pode canalizar essa saída para tr . "$(locale decimal_point)" para corrigi-lo.

Ou, com zsh , você poderia fazer:

printf '%.9f\n' $(($(date -d "$d2" +%s.%N) - $(date -d "$d1" +%s.%N)))

em vez disso, o que lhe dará um número com o separador decimal correto em sua localidade.

No entanto, desde então, zsh usa o formato de número double do seu processador, você pode descobrir que ele fornece um número diferente, pois números como 1493104793.946109551 atingem o limite de precisão desses números. bc não tem o problema, pois usa precisão arbitrária.

zsh tem recursos de análise de tempo embutidos, então também é possível escrever uma solução que funcione em sistemas não-GNU como:

parse_iso8601_full() {
  local t
  typeset -Fg REPLY
  zmodload zsh/datetime
  TZ=UTC0 strftime -r -s t %Y-%m-%dT%H:%M:%S ${1%.*} &&
    REPLY=$t.${${1%Z}##*.}
}

parse_iso8601_full $d1; t1=$REPLY
parse_iso8601_full $d2; t2=$REPLY
printf '%.9f\n' $((t2 - t1))
    
por 25.04.2017 / 14:26