Bagaimana menemukan perbedaan antara dua cap waktu hingga milidetik?

10

Saya baru mengenal shell scripting. Inti dari skrip saya adalah menemukan perbedaan antara dua cap waktu hingga milidetik. Dengan saya, saya punya file dengan isi cap waktu hanya sebagai

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

Seperti ini, saya memiliki sekitar 30k catatan, di mana saya seharusnya tidak menghadapi masalah kinerja ketika saya menjalankan skrip. Banyak faktor seperti tahun kabisat, bulan dengan 31 hari dll muncul ketika saya mencoba menulis skrip untuk ini.

Adakah yang bisa membantu saya dalam hal ini?

Vamshi G
sumber
1
Apakah DST muncul? Lompatan detik? Apa aturan DST? Sudahkah mereka berubah dari waktu ke waktu di negara Anda? Apakah Anda harus berurusan dengan tanggal sebelum tahun 1970, atau sebelum beralih ke kalender gregorian?
Stéphane Chazelas

Jawaban:

13

Tidak perlu melakukan parsing yang kompleks, teman akan melakukan semua keajaiban untuk Anda, dengan bantuan temannya, :

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

KELUARAN

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

Lihat man date

CATATAN

  • date -d sangat berguna, itu mengkonversi cap waktu
  • %sadalah zaman waktu (detik sejak 01-01-1970)
  • %Nadalah nanodetik
  • $(( ))dan (( ))untuk basharitmatika, lihat http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) berdiri untuk command substitution

Apakah ini sesuai dengan kebutuhan Anda juga?

Gilles Quenot
sumber
1
Mengoreksi kesalahan aritmatik (gabungan detik dan nanodetik). Sekarang saya pertama menghitung detik (OP tidak meminta itu, tetapi untuk kelengkapan dan ketahanan dalam penggunaan kembali)
Gilles Quenot
0

Bahasa scripting seperti Perl, Python atau Ruby akan cepat dan membutuhkan sedikit usaha. Misalnya, dengan Perl dan Tanggal :: Parse :

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

(Untuk setiap baris, ganti ,dengan ., pisahkan garis menjadi kata $_[0]- kata $_[3], parsing tanggal yang dibentuk oleh dua kata pertama dan berikutnya, dan cetak perbedaannya.)

Gilles 'SANGAT berhenti menjadi jahat'
sumber
"Usaha kecil" cukup relatif. Tentu, jika Anda seorang programmer X dan tahu tentang perpustakaan Y, itu mudah. Begitulah selalu. Sebenarnya, saya terkejut programmer Python belum masuk ke sini. Saya pikir itu hanya masalah waktu ...: - \
Mike S
Itu sebabnya orang memberikan solusi lengkap di sini. Dengan begitu Anda tidak harus menjadi seorang programmer X atau tahu tentang perpustakaan Y. Dan Anda masih mendapat manfaat dari "sedikit usaha" memiliki satu baris dalam skrip Anda dan bukan 10.
CherryDT
0

Saya baru saja menemukan posting ini, ada - setidaknya hari ini - datesolusi berbasis sederhana . Menggunakan kerangka kerja dalam jawaban @Gilles Quenot (akan menulis komentar untuk servernya, tetapi tidak cukup reputasi):

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

Hasil:

$ ./time_elapsed.sh 
0.007000000

Menggunakan %3Nbukan %Nakan memotong output menjadi milidetik.

Zoltan K.
sumber