Unix döneminden beri milisaniye nasıl elde edilir?


30

Bir tarayıcının başlama zamanını ölçen bir bash betiği yapmak istiyorum, bunun için JavaScript'i kullanarak milisaniyede yüklenen zaman damgasını alan bir html kullanıyorum.

Tarayıcıyı çağırmadan hemen önce kabuk komut dosyasında zaman damgasını alıyorum:

date +%s

Sorun şu ki, saniyeler içinde zaman damgası alıyor ve bazen saniyenin ikinci kez çalıştırıldığı zaman tarayıcı bir saniyenin altında çalışmaya başladığından beri milisaniye cinsinden ihtiyacım var ve bu süreyi saniye yerine milisaniye kullanarak tam olarak ölçebilmeliyim.

Zaman damgasını milisaniye cinsinden bir bash betiğinden nasıl alabilirim?

Yanıtlar:


28

date +%s.%N, örneğin size verecektir., 1364391019.877418748. % N, geçerli saniyede geçen nanosaniye sayısıdır. 9 basamak olduğuna dikkat edin ve varsayılan olarak 100000000'den azsa bu değeri sıfırlarla doldurur. Sayı ile matematik yapmak istiyorsak bu sorun aslında bash, sayıları sekizlik olarak sıfır sayıyor . Bu dolgu, alandaki özellikte kısa çizgi kullanılarak devre dışı bırakılabilir, bu nedenle:

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

o dönemden beri saf bir biçimde milisaniye verirdi.

Ancak , Stephane Chazelas'ın aşağıdaki yorumda işaret ettiği gibi, bu iki farklı dategörüşme sağlayacak iki farklı görüşmedir . İkincisi aralarında geçtiyse, hesaplama tamamıyla kapalı olacaktır. Yani:

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

Veya optimize edilmiş (aşağıdaki açıklamalar sayesinde, bunun açık olması gerekirdi):

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

Denedim ve işe yarıyor, teşekkürler + 1 / kabul et!
Eduard Florinescu

7
İlk tarihi koyduğunuz zaman ile ikinci tarih arasında birkaç milyon nanosaniyenin geçtiğini ve aynı saniye bile olmayabileceğini unutmayın. En iyi yapmak $(($(date +'%s * 1000 + %N / 1000000'))). Bu hala pek mantıklı gelmiyor, ama daha güvenilir olurdu.
Stéphane Chazelas

1

3
%NBSD ve OS X’te mevcut değildir
orkoden

1
Neden sadece değil echo $(( $(date '+%s%N') / 1000000))?
Hitechcomputergeek

47

GNU ya da ast-open uygulamasının date(ya da eğer FEATURE_DATE_NANOseçenek etkinse meşgul) 'nın uygulanmasıyla , şunu kullanırdım:

$ date +%s%3N

Unix döneminden bu yana milisaniye döndüren.


5
Zarif, güzel, +1
Eduard Florinescu

1
Şıklığı için canlandıran
sleepycal 23:17

Gerçekten de zarif, +1. Eğer benim gibi %3N, gerekli sıfır sıfır dolgusunu yaptığınızdan emin olmak istiyorsanız (dokümanları okumadan. ;-), yapabilirsiniz while sleep 0.05; do date +%s%3N; doneve evet, gerekli sıfırlar oradadır.
Terry Brown

Teşekkürler Terry! Ancak %3Ngerçekten sıfır yastıklı. Dahası, çözümünüzün sıfır ekleyeceğini düşünmüyorum, yanıtı hiç bu kadar az geciktirmeyin.
javabeangrinder

javabeangrinder, @ TerryBrown'un kodu bir çözüm değildi , sadece %3Ngerçekten 0-yastıklı olduğunu doğrulamak için test kodu .
Stéphane Chazelas

10

Durumda herkes diğer kabukları daha kullanıyor bash, ksh93ve zshbir kayan noktalı var $SECONDSbir yaparsanız değişken typeset -F SECONDSdoğrulukla süreyi ölçmek için kullanışlı olabilen:

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

Yana sürüm 4.3.13 (2011) zshbir sahiptir $EPOCHREALTIMEnokta değişkeni yüzen special zsh/datetimemodülü:

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

Bunun döndürdüğü iki tamsayıdan (saniye ve nanosaniye için) elde edildiğine dikkat edin clock_gettime(). Çoğu sistemde, tek bir C doublekayan nokta sayısının tutabileceğinden daha fazla hassasiyet gösterir , bu nedenle aritmetik ifadelerde kullandığınızda (1970'in ilk birkaç ayındaki tarihler hariç) hassasiyeti kaybedersiniz.

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

Yüksek hassasiyetli zaman farklarını hesaplamak için (milisaniye hassasiyetinden daha fazlasına ihtiyaç duyacağınızdan şüpheliyim), $epochtimebunun yerine özel diziyi (saniyeler ve nanosaniyeleri iki ayrı eleman olarak içeren) kullanmak isteyebilirsiniz .

5.7 (2018) sürümünden bu yana, strftimekabuk yerleşimi ayrıca bir %NGNU dateve a GNU formatını ve a %.hassasiyetini belirlemek için de destekler , böylece çağdan beri milisaniye sayısı da alınabilir:

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

(veya bir değişkende saklanır -s var)


"$ SECONDS" değişkeninin bağlı değil / EPOCH zamanı ile ilişkili olduğunu unutmayın. Kesirli kısım (milisaniye, mikrosaniye ve nanosaniye) her birinde oldukça farklı olabilir.
Isaac

8

Milisaniyeyi alma hesaplamalarını önlemek için komut satırı JavaScript tercümanları size yardımcı olabilir:

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'da bu tercümanları içeren paketler:


2

Bash olarak 5 + mikro saniye parçalı bir değişken vardır: $EPOCHREALTIME.

Yani:

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

Milisaniye cinsinden dönemden (1/1/70) beri süreyi yazdırır.

Bunu başaramazsan, tarih kullanmalısın. Ya GNU tarihi:

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

Https://serverfault.com/a/423642/465827 adresinde listelenen alternatiflerden biri

Veya brew install coreutilsOS X için

Veya, her şey başarısız olursa, bu c programını derleyin (gcc epochInµsec.c) (gerektiği gibi ayarlayı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;
}

Herhangi bir harici programı çağırmanın okunması ve diskten yüklenmesi, başlatılması, çalıştırılması ve son olarak da çıktının yazdırılması için zamana ihtiyacı olduğunu unutmayın. Bu birkaç milisaniye alacaktır. Herhangi bir harici aletle (tarih dahil) elde edilebilecek asgari hassasiyet budur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.