Como encontrar a diferença entre dois registros de data e hora até milissegundos?

10

Eu sou novo no shell script. O coração do meu script é encontrar a diferença entre dois registros de data e hora até milissegundos. Comigo, tenho um arquivo com conteúdo de timestamps apenas como

2012-09-13 15:00:29,290 2012-09-13 15:00:29,297
2012-09-13 15:00:29,428 2012-09-13 15:00:29,447

Assim, tenho cerca de 30 mil registros, onde não devo enfrentar nenhum problema de desempenho ao executar o script. Muitos fatores como ano bissexto, meses com 31 dias, etc. aparecem quando estou tentando escrever um script para isso.

Alguém pode me ajudar nisso, por favor?

Vamshi G
fonte
1
O horário de verão entra em cena? Segundos bissextos? Quais são as regras do horário de verão? Eles mudaram com o tempo no seu país? Você tem que lidar com datas anteriores a 1970 ou antes de mudar para o calendário gregoriano?
Stéphane Chazelas

Respostas:

13

Não há necessidade de fazer análises complexas, o fará toda a mágica para você, com a ajuda de seu amigo, :

#!/bin/bash
while read d1_1 d1_2 d2_1 d2_2; do
  secdiff=$((
    $(date -d "$d2_1 $d2_2" +%s) - $(date -d "$d1_1 $d1_2" +%s)
  ))
  nanosecdiff=$((
    $(date -d "$d2_1 $d2_2" +%N) - $(date -d "$d1_1 $d1_2" +%N)
  ))
  printf "%s %s - %s %s = %d milliseconds\n" $d2_1 $d2_2 $d1_1 $d1_2 $((
    (secdiff * 1000) + (nanosecdiff / 1000000)
  ))
done < YOUR_FILE.txt

RESULTADO

2012-09-13 15:00:29,297 - 2012-09-13 15:00:29,290 = 7 milliseconds
2012-09-13 15:00:29,447 - 2012-09-13 15:00:29,428 = 19 milliseconds

Vejo man date

NOTA

  • date -d é muito útil, converte timestamps
  • %sé o tempo da época (segundos desde 01-01-1970)
  • %Né nanossegundos
  • $(( ))e (( ))é para basharitmética, consulte http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) apoia command substitution

Isso atende às suas necessidades também?

Gilles Quenot
fonte
1
Corrigido um erro aritmético (concatenando segundos e nanossegundos). Agora eu primeiro computar os segundos (OP não pediu isso, mas está completo e robustez em reutilização)
Gilles Quenot
0

Uma linguagem de script como Perl, Python ou Ruby será rápida e exigirá pouco esforço. Por exemplo, com Perl e Date :: Parse :

perl -MDate::Parse -l -ne 's/,/./g; split; print str2time("$_[2] $_[3]") - str2time("$_[0] $_[1]")'

(Para cada linha, substitua ,por ., dividir a linha em palavras $_[0]através $_[3], analisar as datas formados pelos dois primeiros e próximas duas palavras, e imprimir a diferença.)

Gilles 'SO- parar de ser mau'
fonte
"Pouco esforço" é bastante relativo. Claro, se você é um programador X e conhece a biblioteca Y, é muito fácil. É assim que sempre é. Na verdade, estou surpreso que um programador Python ainda não tenha entrado aqui. Eu acho que é apenas uma questão de tempo ...: - \
Mike S
0

Acabei de encontrar este post, há - pelo menos hoje - uma datesolução mais simples . Usando a estrutura na resposta de @Gilles Quenot (teria escrito um comentário à sua resposta, mas não a reputação suficiente):

while read d1_1 d1_2 d2_1 d2_2
do
    date -d "$d2_1 $d2_2 $(date -d "$d1_1 $d1_2" +%s.%N) seconds ago" +%s.%N
done << END
2012-09-13 15:00:29,290 2012-09-13 15:00:29,297
END

O resultado:

$ ./time_elapsed.sh 
0.007000000

Usar em %3Nvez de %Ntruncará a saída em milissegundos.

Zoltan K.
fonte