Comment trouver la différence entre deux horodatages jusqu'à quelques millisecondes?

10

Je suis nouveau dans les scripts shell. Le cœur de mon script est de trouver la différence entre deux horodatages jusqu'à quelques millisecondes. Avec moi, j'ai un fichier avec le contenu des horodatages uniquement

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

Comme cela, j'ai environ 30k enregistrements, où je ne devrais pas rencontrer de problème de performance lorsque j'exécute un script. De nombreux facteurs comme l'année bissextile, les mois avec 31 jours, etc. entrent en jeu lorsque j'essaie d'écrire un script pour cela.

Quelqu'un peut-il m'aider à ce sujet s'il vous plaît?

Vamshi G
la source
1
Est-ce que l'heure d'été entre en scène? Leap seconds? Quelles sont les règles DST? Ont-ils changé au fil du temps dans votre pays? Devez-vous faire face à des dates antérieures à 1970, ou avant de passer au calendrier grégorien?
Stéphane Chazelas

Réponses:

13

Pas besoin de faire une analyse complexe, fera toute la magie pour vous, avec l'aide de son ami :

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

PRODUCTION

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

Voir man date

REMARQUE

  • date -d est très utile, il convertit les horodatages
  • %sest le temps de l' époque (secondes depuis le 01-01-1970)
  • %Nest nanosecondes
  • $(( ))et (( ))est pour l' basharithmétique, voir http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) signifie command substitution

Est-ce que cela correspond aussi à vos besoins?

Gilles Quenot
la source
1
Correction d' une erreur arithhmétique (concaténation des secondes et des nanosecondes). Maintenant, je calcule d'abord les secondes (OP ne me l'a pas demandé, mais pour la complétude et la robustesse lors de la réutilisation)
Gilles Quenot
0

Un langage de script tel que Perl, Python ou Ruby sera rapide et nécessitera peu d'efforts. Par exemple, avec Perl et Date :: Parse :

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

(Pour chaque ligne, remplacer ,par ., diviser la ligne en mots à $_[0]travers $_[3], analyser les dates formées par les deux premières et deux mots, et imprimer la différence.)

Gilles 'SO- arrête d'être méchant'
la source
"Peu d'efforts" est assez relatif. Bien sûr, si vous êtes un programmeur X et connaissez la bibliothèque Y, c'est un jeu d'enfant. C'est toujours comme ça. En fait, je suis surpris qu'un programmeur Python ne soit pas encore intervenu ici. Je pense que c'est juste une question de temps ...: - \
Mike S
0

Je viens de tomber sur ce post, il existe - au moins aujourd'hui - une datesolution plus simple . Utilisation du cadre dans la réponse de @Gilles Quenot (aurait écrit un commentaire à sa réponse, mais pas assez de réputation):

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

Le résultat:

$ ./time_elapsed.sh 
0.007000000

L'utilisation de %3Nau lieu de %Ntronquera la sortie en millisecondes.

Zoltan K.
la source