Come trovare la differenza tra due timestamp fino a millisecondi?


10

Sono nuovo di shell scripting. Il cuore della mia sceneggiatura è trovare la differenza tra due timestamp fino a millisecondi. Con me ho un file con contenuto di timestamp solo come

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

In questo modo ho circa 30k record, in cui non dovrei affrontare alcun problema di prestazioni quando eseguo lo script. Molti fattori come l'anno bisestile, i mesi con 31 giorni ecc. Entrano in scena quando sto cercando di scrivere una sceneggiatura per questo.

Qualcuno può aiutarmi su questo per favore?


1
L'ora legale entra in scena? Saltare secondi? Quali sono le regole dell'ora legale? Sono cambiati nel tempo nel tuo paese? Devi avere a che fare con le date prima del 1970 o prima di passare al calendario gregoriano?
Stéphane Chazelas,

Risposte:


13

Non è necessario eseguire analisi complesse, la farà tutta la magia per te, con l'aiuto del suo amico, :

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

PRODUZIONE

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

Vedere man date

NOTA

  • date -d è molto utile, converte i timestamp
  • %sè il tempo di epoca (secondi dal 01-01-1970)
  • %Nè nanosecondi
  • $(( ))ed (( ))è per l' basharitmetica, vedi http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) sta per command substitution

È adatto anche alle tue esigenze?


1
Corretto un errore aritmetico (concatenando secondi e nanosecondi). Ora prima calcolo i secondi (OP non lo ha chiesto, ma per completezza e robustezza nel riutilizzo)
Gilles Quenot,

0

Un linguaggio di scripting come Perl, Python o Ruby sarà veloce e richiederà poco sforzo. Ad esempio, con Perl e Date :: Parse :

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

(Per ogni riga, sostituire ,con. , dividere la linea in parole $_[0]attraverso $_[3], analizzare le date formate dai primi due e due parole successive, e stampare la differenza.)


"Piccolo sforzo" è abbastanza relativo. Certo, se sei un programmatore X e conosci la libreria Y, è un gioco da ragazzi. È sempre così. In realtà, sono sorpreso che un programmatore di Python non sia ancora arrivato qui. Immagino sia solo una questione di tempo ...: - \
Mike S il

Ecco perché la gente offre una soluzione completa qui. In questo modo non devi essere un programmatore X o conoscere la libreria Y. E beneficiate ancora del "piccolo sforzo" di avere una riga nella sceneggiatura e non il 10
CherryDT

0

Mi sono appena imbattuto in questo post, c'è - almeno oggi - uno più semplice date soluzione . Utilizzando il framework nella risposta di @Gilles Quenot (avrebbe scritto un commento alla sua risposta, ma non abbastanza reputazione):

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

Il risultato:

$ ./time_elapsed.sh 
0.007000000

L'uso di %3Ninvece di %Ntronca l'output in millisecondi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.