Làm thế nào để có được mili giây kể từ Unix epoch?


30

Tôi muốn thực hiện một tập lệnh bash để đo thời gian khởi chạy của trình duyệt mà tôi đang sử dụng một html có thời gian tải về thời gian tính bằng mili giây bằng JavaScript.

Trong kịch bản shell ngay trước khi tôi gọi trình duyệt, tôi nhận được dấu thời gian với:

date +%s

Vấn đề là nó có dấu thời gian tính bằng giây và tôi cần nó tính bằng mili giây vì đôi khi khi chạy lần thứ hai, trình duyệt bắt đầu dưới một giây và tôi cần có thể đo chính xác thời gian đó bằng mili giây thay vì giây.

Làm cách nào tôi có thể lấy dấu thời gian tính bằng mili giây từ tập lệnh bash?

Câu trả lời:


28

date +%s.%Nsẽ cung cấp cho bạn, ví dụ 1364391019.877418748. % N là số lượng nano giây trôi qua trong giây hiện tại. Lưu ý rằng nó có 9 chữ số và theo mặc định ngày sẽ điền số này vào các số 0 nếu nó nhỏ hơn 100000000. Đây thực sự là một vấn đề nếu chúng ta muốn làm toán với số đó, vì bash coi các số có số 0 đứng đầu là bát phân . Phần đệm này có thể được tắt bằng cách sử dụng dấu gạch nối trong thông số trường, vì vậy:

echo $((`date +%s`*1000+`date +%-N`/1000000))

ngây thơ sẽ cho bạn một phần nghìn giây kể từ thời đại.

Tuy nhiên , như Stephane Chazelas chỉ ra trong bình luận bên dưới, đó là hai datecuộc gọi khác nhau sẽ mang lại hai thời điểm hơi khác nhau. Nếu cái thứ hai lăn qua giữa chúng, phép tính sẽ bị tắt toàn bộ giây. Vì thế:

echo $(($(date +'%s * 1000 + %-N / 1000000')))

Hoặc được tối ưu hóa (nhờ các bình luận bên dưới, mặc dù điều này đáng lẽ phải rõ ràng):

echo $(( $(date '+%s%N') / 1000000));

Tôi đã thử nó và nó hoạt động, cảm ơn + 1 / chấp nhận!
Eduard Florinescu

7
Lưu ý rằng trong khoảng thời gian bạn chạy ngày đầu tiên và ngày thứ hai, vài triệu nano giây có thể đã trôi qua và nó thậm chí có thể không phải là cùng một giây. Tốt nhất để làm $(($(date +'%s * 1000 + %N / 1000000'))). Điều đó vẫn không có ý nghĩa nhiều, nhưng sẽ đáng tin cậy hơn.
Stéphane Chazelas

1
Đã sửa lỗi bằng cách tắt phần đệm bằng 0 như ghi chú trong ngày (1)
Alois Mahdal

3
%Nkhông có sẵn trong BSD và OS X.
orkoden

1
Tại sao không chỉ echo $(( $(date '+%s%N') / 1000000))?
Hitechcomputergeek

47

Với việc triển khai GNU hoặc ast-open của date(hoặc busybox 'nếu được xây dựng với FEATURE_DATE_NANOtùy chọn được bật), tôi sẽ sử dụng:

$ date +%s%3N

trả về mili giây kể từ Unix epoch.


5
Thanh lịch, tốt đẹp, +1
Eduard Florinescu

1
Nâng cao sự thanh lịch
ngủ

Quả thực thanh lịch, +1. Nếu giống như tôi, bạn muốn chắc chắn rằng %3Nphần đệm không cần thiết còn lại (không cần đọc tài liệu. ;-), bạn có thể làm while sleep 0.05; do date +%s%3N; done, và vâng, các số không cần thiết nằm trong đó.
Terry Brown

Cảm ơn bạn Terry! Tuy nhiên, %3Nthực sự là không có đệm. Hơn nữa, tôi không nghĩ rằng giải pháp của bạn sẽ thêm số không, chỉ cần trì hoãn phản hồi rất ít.
javabeangrinder

javabeangrinder, mã của @ TerryBrown không phải là một giải pháp , chỉ cần kiểm tra mã để xác minh đó %3Nthực sự là 0-độn.
Stéphane Chazelas

10

Trong trường hợp bất cứ ai đang sử dụng vỏ ngoài bash, ksh93zshcó một điểm nổi $SECONDSbiến nếu bạn làm một typeset -F SECONDSmà có thể thuận tiện để đo thời gian với độ chính xác:

$ typeset -F SECONDS=0
$ do-something
something done
$ echo "$SECONDS seconds have elapsed"
18.3994340000 seconds have elapsed

Do phiên bản 4.3.13 (2011) zsh$EPOCHREALTIMEbiến số dấu phẩy động đặc biệt trong zsh/datetimemô-đun:

$ zmodload zsh/datetime
$ echo $EPOCHREALTIME
1364401642.2725396156
$ printf '%d\n' $((EPOCHREALTIME*1000))
1364401755993

Lưu ý rằng đó là xuất phát từ hai số nguyên (tính bằng giây và nano giây) được trả về clock_gettime(). Trên hầu hết các hệ thống, độ chính xác cao hơn doublesố dấu phẩy động C có thể giữ được, do đó bạn sẽ mất độ chính xác khi bạn sử dụng nó trong các biểu thức số học (ngoại trừ ngày trong vài tháng đầu năm 1970).

$ t=$EPOCHREALTIME
$ echo $t $((t))
1568473231.6078064442 1568473231.6078064

Để tính toán chênh lệch thời gian chính xác cao (mặc dù tôi nghi ngờ bạn cần nhiều hơn độ chính xác mili giây), bạn có thể muốn sử dụng $epochtimemảng đặc biệt thay thế (chứa giây và nano giây như hai yếu tố riêng biệt).

Kể từ phiên bản 5.7 (2018) các strftimeBUILTIN vỏ cũng hỗ trợ một %Nđịnh dạng nano giây à la GNU datevà một %.để xác định chính xác, vì vậy số mili giây kể từ khi kỷ nguyên cũng có thể được lấy ra với:

zmodload zsh/datetime
strftime %s%3. $epochtime

(hoặc được lưu trữ trong một biến với -s var)


Lưu ý rằng biến "$ GIÂY" không được kết nối / liên quan đến thời gian EPOCH. Phần phân số (mili giây, micro giây và nano giây) có thể khá khác nhau trong mỗi phần.
Isaac

8

Để tránh tính toán để có được mili giây, trình thông dịch JavaScript dòng lệnh có thể giúp:

bash-4.2$ node -e 'console.log(new Date().getTime())' # node.js
1364391220596

bash-4.2$ js60 -e 'print(new Date().getTime())'       # SpiderMonkey
1364391220610

bash-4.2$ jsc -e 'print(new Date().getTime())'        # WebKit 
1364391220622

bash-4.2$ seed -e 'new Date().getTime()'              # GNOME object bridge
1364391220669

Các gói chứa các thông dịch viên trên Ubuntu Eoan:


2

Trong bash 5+ có một biến có độ chi tiết micro-giây : $EPOCHREALTIME.

Vì thế:

$ echo "$(( ${EPOCHREALTIME//.} / 1000 ))"
1568385422635

In thời gian kể từ epoch (1/1/70) tính bằng milisecond.

Không, bạn phải sử dụng ngày. Ngày GNU:

echo "$(date +'%s%3N')"

Một trong những lựa chọn thay thế được liệt kê trong https://serverfault.com/a/423642/465827

Hoặc brew install coreutilscho OS X

Hoặc, nếu mọi thứ khác không thành công, hãy biên dịch (gcc epochIn hèsec.c) chương trình c này (điều chỉnh khi cần):

#include <stdio.h>
#include <sys/time.h>
int main(void)
{
  struct timeval time_now;
    gettimeofday(&time_now,NULL);
    printf ("%ld secs, %ld usecs\n",time_now.tv_sec,time_now.tv_usec);

    return 0;
}

Lưu ý rằng việc gọi bất kỳ chương trình bên ngoài nào cũng cần thời gian để đọc và tải từ đĩa, bắt đầu, chạy và cuối cùng để in đầu ra. Điều đó sẽ mất vài mili giây. Đó là độ chính xác tối thiểu có thể đạt được với bất kỳ công cụ bên ngoài nào (bao gồm cả ngà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.