Unixエポックからミリ秒を取得する方法は?


30

JavaScriptを使用してミリ秒単位でタイムスタンプのロードを取得するhtmlを使用しているため、ブラウザの起動時間を測定するbashスクリプトを実行したいです。

ブラウザを呼び出す直前のシェルスクリプトで、次のタイムスタンプを取得します。

date +%s

問題は、タイムスタンプを秒単位で取得することです。また、ブラウザを1秒未満で2回目に起動したときに、秒ではなくミリ秒を使用して正確にその時間を測定できる必要があるため、ミリ秒単位で必要です。

bashスクリプトからミリ秒単位のタイムスタンプを取得するにはどうすればよいですか?

回答:


28

date +%s.%N例えば、あなたを与えるだろう。、 1364391019.877418748。%Nは、現在の秒で経過したナノ秒数です。これは9桁であり、デフォルトでは日付が100000000未満の場合、これにゼロが埋め込まれます。これは、bashが先行ゼロの数字を8進数として扱うため、数値で計算する場合に実際に問題になります。このパディングは、フィールド仕様でハイフンを使用することにより無効にできます。

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

エポックからのミリ秒を単純に与えます。

ただし、Stephane Chazelasが以下のコメントで指摘しているように、それは2つの異なるdate呼び出しであり、わずかに異なる2つの時間をもたらします。秒がそれらの間でロールオーバーした場合、計算は完全に1秒オフになります。そう:

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

または最適化(これは明白なはずですが、以下のコメントのおかげです):

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

私はそれを試してみましたが、機能します、+ 1 / accept!
エデュアルドフロリネスク

7
最初の日付を実行してから2番目の日付を実行するまでの間に、数百万ナノ秒が経過した可能性があり、同じ秒でさえない可能性があることに注意してください。するのがベスト$(($(date +'%s * 1000 + %N / 1000000')))。それはまだあまり意味がありませんが、より信頼できるでしょう。
ステファンシャゼル

1
date(1)に記載されているようにゼロパディングをオフにすることで修正
Alois Mahdal

3
%NBSDおよびOS Xでは使用できません。
orkoden15年

1
どうしてecho $(( $(date '+%s%N') / 1000000))
Hitechcomputergeek

47

GNUまたはast-open実装date(またはFEATURE_DATE_NANOオプションを有効にしてビルドした場合はbusybox )を使用すると、次のように使用できます。

$ date +%s%3N

Unixエポックからのミリ秒を返します。


5
エレガントな素敵な+1
エデュアルドフロリネスク14

1
優雅さへの
賛成

確かに、+ 1。私のように%3N、ドキュメントを読むことなく、必要な左ゼロのパディングを確実にしたい場合は、行うことができますwhile sleep 0.05; do date +%s%3N; done、はい、必要なゼロはそこにあります。
テリーブラウン

テリーありがとう!ただし%3N、実際にはゼロが埋め込まれます。さらに、あなたのソリューションがゼロを追加することはないと思います。応答を少し遅らせるだけです。
javabeangrinder

javabeangrinder、@ TerryBrownのコードは解決策ではなく、コードをテストし%3Nて実際に0が埋め込まれていることを確認するだけです。
ステファンシャゼル

10

場合には誰でも以外のシェルを使用しているbashksh93zsh浮動小数点持って$SECONDSあなたが行う場合は、変数をtypeset -F SECONDS正確に時間を測定するために便利なことができました:

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

バージョン4.3.13(2011)以来zsh有する$EPOCHREALTIMEにおける特別な浮動小数点変数zsh/datetimeモジュール。

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

これは、によって返される2つの整数(秒とナノ秒)から導出されることに注意してくださいclock_gettime()。ほとんどのシステムでは、1つのC double浮動小数点数が保持できる精度よりも高いため、算術式で使用すると精度が低下します(1970年の最初の数か月の日付を除く)。

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

高精度の時間差を計算するには(ミリ秒以上の精度が必要になるとは思いませんが)、$epochtime代わりに特別な配列(秒とナノ秒を2つの別個の要素として含む)を使用することができます。

バージョン5.7(2018)以降、strftimeシェルのビルトインは%Nナノ秒形式のGNU dateおよびa %.をサポートし、精度を指定するため、エポックからのミリ秒数も取得できます。

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

(またはで変数に保存-s var


変数「$ SECONDS」は、EPOCH時間に接続/関連していないことに注意してください。小数部分(ミリ秒、マイクロ秒、ナノ秒)はそれぞれ非常に異なる場合があります。
アイザック

8

ミリ秒を取得するための計算を回避するために、コマンドラインJavaScriptインタープリターが役立つ場合があります。

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

Ubuntu Eoanにこれらのインタープリターを含むパッケージ:


2

bash 5+には、マイクロ秒の粒度の変数があります$EPOCHREALTIME

そう:

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

エポック(1/1/70)からの時間をミリ秒単位で出力します。

それに失敗すると、日付を使用する必要があります。GNU日付:

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

https://serverfault.com/a/423642/465827にリストされている代替手段の1つ

またはbrew install coreutilsOS Xの場合

または、他のすべてが失敗した場合、このcプログラムをコンパイル(gcc epochInµsec.c)(必要に応じて調整):

#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;
}

外部プログラムを呼び出すには、ディスクから読み込んでロードし、開始し、実行し、最後に出力を印刷する時間が必要であることに注意してください。それには数ミリ秒かかります。これは、外部ツール(日付を含む)で達成できる最小精度です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.