web-dev-qa-db-ja.com

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

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

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

date +%s

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

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

32

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));
29
goldilocks

GNUまたはdateのast-open実装(またはFEATURE_DATE_NANOオプションが有効)、私は次のように使用します:

$ date +%s%3N

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

50
javabeangrinder

誰かがbash以外のシェルを使用している場合、_ksh93_を実行すると、_$SECONDS_およびzshに浮動小数点変数_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
_

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

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

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

バージョン5.7(2018)以降、strftime Shellビルトインは_%N_ナノ秒フォーマットàla GNU dateおよび_%._もサポートします精度を指定するため、エポック以降のミリ秒数も次のようにして取得できます。

_zmodload zsh/datetime
strftime %s%3. $epochtime
_

(または_-s var_で変数に格納)

11

ミリ秒を取得するための計算を回避するには、コマンドライン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上のこれらのインタープリターを含むパッケージ:

8
manatwork

Bash 5+には、マイクロ秒の粒度を持つ変数があります:$EPOCHREALTIME

そう:

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

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

それができない場合は、日付を使用する必要があります。 GNU日付:

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

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

またはbrew install coreutils for OS 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;
}

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

3
Isaac