Làm thế nào để tìm sự khác biệt giữa hai dấu thời gian lên đến mili giây?


10

Tôi mới sử dụng shell scripting. Trọng tâm của kịch bản của tôi là tìm ra sự khác biệt giữa hai dấu thời gian lên đến mili giây. Với tôi, tôi có một tệp có nội dung dấu thời gian chỉ là

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

Như thế này tôi có khoảng 30k hồ sơ, nơi tôi không phải đối mặt với bất kỳ vấn đề hiệu suất nào khi tôi thực thi tập lệnh. Nhiều yếu tố như năm nhuận, tháng với 31 ngày v.v ... xuất hiện khi tôi đang cố gắng viết kịch bản cho việc này.

Ai có thể giúp tôi về điều này xin vui lòng?


1
DST có đi vào hình ảnh không? Leap giây? Các quy tắc DST là gì? Họ đã thay đổi theo thời gian ở nước bạn? Bạn có phải đối phó với ngày trước năm 1970, hoặc trước khi chuyển sang lịch gregorian?
Stéphane Chazelas

Câu trả lời:


13

Không cần phải phân tích cú pháp phức tạp, sẽ làm tất cả điều kỳ diệu cho bạn, với sự giúp đỡ của bạn mình, :

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

ĐẦU RA

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

Xem man date

GHI CHÚ

  • date -d là rất hữu ích, nó chuyển đổi dấu thời gian
  • %sthời gian kỷ nguyên (giây kể từ ngày 01-01-1970)
  • %Nnano giây
  • $(( ))(( ))dành cho bashsố học, xem http://mywiki.wooledge.org/ArithaturesExpression
  • $( ) là viết tắt của command substitution

Điều này có phù hợp với nhu cầu của bạn không?


1
Điều chỉnh một arithhmetic lỗi (concatenating giây và nano giây). Bây giờ tôi lần đầu tiên tính toán giây (OP không hỏi điều đó, nhưng để hoàn thiện và mạnh mẽ trong việc sử dụng lại)
Gilles Quenot

0

Một ngôn ngữ kịch bản như Perl, Python hoặc Ruby sẽ nhanh và đòi hỏi ít nỗ lực. Ví dụ: với Perl và Date :: Parse :

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

(Đối với mỗi dòng, thay thế ,bằng ., chia dòng thành các từ $_[0]thông qua $_[3], phân tích ngày tháng được tạo bởi hai từ đầu tiên và hai từ tiếp theo và in sự khác biệt.)


"Ít nỗ lực" là khá tương đối. Chắc chắn, nếu bạn là một lập trình viên X và biết về thư viện Y, thì đó là một cinch. Đó là cách nó luôn luôn như vậy. Trên thực tế, tôi ngạc nhiên khi một lập trình viên Python chưa nhảy vào đây. Tôi nghĩ đó chỉ là vấn đề thời gian ...: - \
Mike S

0

Tôi vừa xem qua bài đăng này, có - ít nhất là ngày hôm nay - một dategiải pháp dựa trên đơn giản hơn . Sử dụng khuôn khổ trong câu trả lời của @Gilles Quenot (sẽ viết một bình luận cho anwser của anh ta, nhưng không đủ danh tiếng):

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

Kết quả:

$ ./time_elapsed.sh 
0.007000000

Sử dụng %3Nthay vì %Nsẽ cắt đầu ra thành mili giây.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.