Jak znaleźć różnicę między dwoma znacznikami czasu do milisekund?

10

Jestem nowy w skryptowaniu powłoki. Serce mojego skryptu polega na znalezieniu różnicy między dwoma znacznikami czasu do milisekund. Ze mną mam plik z zawartością znaczników czasu tylko jako

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

W ten sposób mam około 30 000 rekordów, w których nie powinienem napotykać żadnych problemów z wydajnością podczas wykonywania skryptu. Wiele czynników, takich jak rok przestępny, miesiące z 31 dniami itp., Pojawia się, gdy próbuję napisać skrypt dla tego.

Czy ktoś może mi pomóc w tej sprawie?

Vamshi G.
źródło
1
Czy na zdjęciu pojawia się DST? Skok sekund? Jakie są zasady DST? Czy zmieniły się z czasem w twoim kraju? Czy masz do czynienia z datami sprzed 1970 roku, czy przed przejściem na kalendarz gregoriański?
Stéphane Chazelas,

Odpowiedzi:

13

Nie musisz wykonywać skomplikowanej analizy, zrobi dla ciebie całą magię, z pomocą swojego przyjaciela, :

#!/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

WYNIK

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

Widzieć man date

UWAGA

  • date -d jest bardzo przydatny, konwertuje znaczniki czasu
  • %sto czas epoki (sekundy od 01-01-1970)
  • %Nto nanosekundy
  • $(( ))i (( ))dotyczy basharytmetyki, patrz http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) oznacza command substitution

Czy to również pasuje do twoich potrzeb?

Gilles Quenot
źródło
1
Poprawiono błąd arytmetyczny (łączenie sekund i nanosekund). Teraz najpierw obliczam sekundy (OP nie pyta o to, ale dla kompletności i niezawodności w ponownym użyciu)
Gilles Quenot,
0

Język skryptowy, taki jak Perl, Python lub Ruby, będzie szybki i nie będzie wymagał dużego wysiłku. Na przykład z Perl i Date :: Parse :

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

(Dla każdej linii, zastąpić ,przez ., podzielić linię na słowa $_[0]przez $_[3], analizowania daty utworzone przez dwóch pierwszych i kolejnych dwóch wyrazów, a następnie wydrukować różnicę).

Gilles „SO- przestań być zły”
źródło
„Mały wysiłek” jest dość względny. Jasne, jeśli jesteś programistą X i znasz bibliotekę Y, jest to bardzo proste. Tak to zawsze jest. Jestem zaskoczony, że programista Python jeszcze tu nie wskoczył. Myślę, że to tylko kwestia czasu ...: - \
Mike S
Dlatego ludzie dają tutaj pełne rozwiązanie. W ten sposób nie musisz być programistą X ani wiedzieć o bibliotece Y. I nadal
czerpiesz
0

Właśnie natrafiłem na ten post, istnieje - przynajmniej dzisiaj - prostsze daterozwiązanie. Korzystając z frameworka w odpowiedzi na @Gilles Quenot (napisałby komentarz do swojej odpowiedzi, ale za mało reputacji):

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

Wynik:

$ ./time_elapsed.sh 
0.007000000

Użycie %3Nzamiast %Nspowoduje skrócenie wyniku do milisekund.

Zoltan K.
źródło