Şu andaki Unix zamanını milisaniye cinsinden bash cinsinden nasıl edinebilirim?


232

Mevcut Unix zamanını milisaniye cinsinden nasıl alabilirim (yani, 1 Ocak 1970’deki Unix döneminden bu yana geçen milisaniye sayısı)?

Yanıtlar:


264

Bu:

date +%s 

dönemin üzerinden saniye sayısını döndürür .

Bu:

date +%s%N

saniye ve geçerli nanosaniye değerini döndürür.

Yani:

date +%s%N | cut -b1-13

Şimdiki saniye artı nanosaniyenin sol üçü - şimdiki zamandan bu yana milisaniye sayısını verecektir.


ve MikeyB'den - echo $(($(date +%s%N)/1000000))(1000'e bölünmesi yalnızca mikrosaniye değerine ulaşır )


39
Kesimin kaç ms ekleyeceğini merak ediyorum :-)
Kyle Brandt

13
Ya da hepsini kabuğun içinde yapmak istiyorsanız, ek bir işlemin pahalı masraflarından kaçınarak (aslında,% + s + N içindeki basamakların sayısı değiştiğinde echo $(($(date +%s%N)/1000))
sorundan kaçınıyoruz

5
Meselenin prensibi ... sihirli sayılardan kaçınmak ve gerçekte ne demek istediğini kodlamak .
MikeyB

25
Sanırım adamın Linux değil Unix istediğini ve şu anki en iyi cevabın (tarih +% s% N) AIX sistemimde işe yaramadığını kaydetmeye değer.
Pete

12
@Pete +1 OS X ve FreeBSD için aynı
ocodo

99

%3NNanosaniyeyi, en önemli 3 haneye (sonra milisaniye olan) kesmek için kullanabilirsiniz :

$ date +%s%3N
1397392146866

Bu, örneğin benim kubuntu 12.04 üzerinde çalışıyor.

Ancak %N, hedef sisteminize bağlı olarak uygulanamayabileceğini unutmayın. Örneğin, gömülü bir sistemde test edilmiştir (HF olmayan bir kol çapraz alet zinciri kullanılarak derlenmiş kök kökler) %N:

$ date +%s%3N
1397392146%3N

(Ayrıca benim (köklü olmayan) Android tabletim de yok %N).


1
@warren: Ben düzenlediğiniz olduğunu gördü ve değiştirdi 1397392146%3Netmek 1397392146%N, ancak çıkış 1397392146%3NGerçekten benim android tablet busybox konsolda gördüğü şey olmasıdır. Düzenlemenizi açıklayabilir misiniz?
Joe

warren'ın tarihteki yorumu "3'ten 6'ya değiştirildiği için 3'ten 6'ya değiştirildi". Düzenlemesi tamamen sahte görünüyor; geri almalısın.
bukzor

1
Bu, özellikle GNU coreutils'in bir özelliğidir. Sonuçta bu, burada gnulib'de uygulanmaktadır: github.com/gagern/gnulib/blob/… .
telotortium

Muhtemelen orada bir nokta mantıklı. date +%s.%3Nyazdırır 1510718281.134.
04

Bu kabul edilen cevap olmalı.
Noah Sussman,

61

date +%N OS X üzerinde çalışmıyor, ancak bir tanesini kullanabilirsiniz.

  • yakut: ruby -e 'puts Time.now.to_f'
  • piton: python -c 'import time; print time.time()'
  • node.js: node -e 'console.log(Date.now())'
  • PHP: php -r 'echo microtime(TRUE);'
  • iksir: DateTime.utc_now() |> DateTime.to_unix(:millisecond)
  • internetler: wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
  • veya en yakın ikinci yuvarlanan milisaniye date +%s000

1
bütünlüğü için ...node -e 'console.log(Date.now())'
slf

1
PHP Kullanımı:php -r 'echo microtime(TRUE);'
TachyonVortex 22:13

8
Tabii, sadece tercümanların ısınmasını beklemelisin. Bu da çalışır:wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
Camilo Martin

8
Veya, aslında milisaniyelere ihtiyacınız yoksa, sadece doğru formata ihtiyacınız varsa :date +%s000
Lenar Hoyt 22:15

1
apple.stackexchange.com/questions/135742/... demlemek en aracılığı OSX bunu yapmaya yönelik talimatlar bulunurcoreutils
sameers

9

Sadece bunu fırlatıp atıyorum, ama bence bu bölünme ile doğru formül:

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

9

Benim çözümüm en iyisi değil, benim için çalıştı.

date +%s000

Sadece 2012-05-05 gibi bir tarihi milisaniyeye dönüştürmem gerekiyordu.


1
İnanılmaz kesmek, lol :)
k06a

7
İş arkadaşlarım arasında biri olmalısın.
Nakilon

7

Harici programları çalıştırmayı önerenlerin ... ... bu saniyedeki mili saniyeyi ... ... alabilmelerini öneren insanlar için, şunu da yapabilirsin:

wget -qO- http://www.timeapi.org/utc/now?\\s.\\N

Olma noktası: buradan herhangi bir cevap seçmeden önce, lütfen tüm programların bir saniyenin altında çalışmayacağını unutmayın. Ölçmek, ölçü,,, tedbir, önlem!


Yerel sisteme zaman sormuyorsun. Sanırım soruda ima ediliyor. Ayrıca bir ağ bağlantısına da bağlıdır.
orkoden

2
@orkoden Soru açıkça “1 Ocak 1970’ten beri Unix döneminden bu yana geçen milisaniye sayısını” soruyor. Ayrıca, daha fazla zaman ayırmak için Ruby veya Python'un (ya da tümünün) nasıl ateşlenmemesi gerektiğine daha fazla dikkat ediyorum - ya bu hızlı bir kanaldan yapılıyor ya da milisaniye önemli değil.
Camilo Martin

2
Evet, kötü çözümlerin kusurlarını vurgulamak için daha kötü bir çözüm verdiğinizi anladım. Birkaç çözüm denedim ve zamanı ölçtüm. lpaste.net/119499 Sonuçlar biraz ilginç. Çok hızlı bir i7 makinede bile dateçalışması 3 ms sürer.
orkoden

@orkoden Güzel test! Hangi işletim sistemi? Bunun genel gider süreciyle ilgisi olabilir.
Camilo Martin

1
@Nakilon ve işte bu yüzden, herhangi bir şey için olduğu gibi kıvrılabilir özelliklere güvenilmemelidir.
Camilo Martin

4

bu çözüm macOS'ta çalışır.

bash betiği kullanmayı düşünüyorsanız ve python'unuz varsa, şu kodu kullanabilirsiniz:

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'

neden aşağı oy?
Frank Thonig

Özellikle haklı görünmüyor. Aşağı ok ile ilgili ipucu "Bu cevap yararlı değil" diyor, ancak IMO kullanışlıdır. Belki onun yerine Python betiği yapmanı istediler. Bu daha basit olurdu ve ayrıca bir bash komutu olarak iyi çalışır.
Andrew Schulman,

Düşüşler hakkında çok fazla endişelenmeyin (benim değildi) ... özellikle anonim ise (hangisi neyin yanlış gibi göründüğünü öğrenemez). Sadece onu işlemenizi kolaylaştırmak için ... işte bir +1 daha gidiyor ... tahmin et ne: SİZİN de artık "oy kullanma" izniniz var değil mi?
Pierre.Vriens

Olumsuz oy sistemle ilgili bir sorundan kaynaklanmış gibi görünüyor. O zamandan beri, sistem tarafından tekrar kaldırıldı.
Michael Hampton

2

Komut dosyanızın çalışma süresini görüntülemenin bir yolunu arıyorsanız, aşağıdakiler (tam olarak doğru değil) bir sonuç verecektir:

Komut dosyanızın başına olabildiğince yakın, aşağıdakini girin

basetime=$(date +%s%N)

Bu size 1361802943996000000 gibi bir başlangıç ​​değeri verir.

Komut dosyanızın sonunda aşağıdakileri kullanın

echo "runtime: $(echo "scale=3;($(date +%s%N) - ${basetime})/(1*10^09)" | bc) seconds"

hangi gibi bir şey gösterecektir

runtime: 12.383 seconds

Notlar:

(1 * 10 ^ 09) isterseniz 1000000000 ile değiştirilebilir

"scale=3"bcİstediğinizi yapmaya zorlayan nadir bir ayardır . Çok daha fazlası var!

Bunu sadece Win7 / MinGW'de test ettim ... Elime uygun bir * nix kutum yok.


3
ya da sadece kullanabilirsiniztime <script>
warren

2

İşte bölme yapmadan milisaniye cinsinden nasıl zaman alacağınız. Belki daha hızlıdır ...

# test=`date +%s%N`
# testnum=${#test}
# echo ${test:0:$testnum-6}
1297327781715

Güncelleme: Saf bashta sadece birlikte çalışan başka bir alternatif bash 4.2+yukarıdaki ile aynıdır ancak printftarihi almak için kullanın . Kesinlikle daha hızlı olacak çünkü ana süreçten hiçbir işlem yapılmadı.

printf -v test '%(%s%N)T' -1
testnum=${#test}
echo ${test:0:$testnum-6}

Yine de buradaki diğer bir nokta, strftimeuygulamanızın desteklemesi gerektiği %sve %Ntest makinemde geçerli olmayan hangisinin olduğu. man strftimeDesteklenen seçenekler için bkz . Ayrıca sözdizimini görmek man bashiçin bkz printf. -1ve -2zaman için özel değerlerdir.


Ne biz gibi görünüyor strftime(3)desteklemiyor %Nöylesine için hiçbir şekilde printfnanosaniye yazdırmak için. Ubuntu 14.04 kullanıyorum.
haridsv

@haridsv, evet, glibc'de değil. datedaha güvenilir bir seçenek gibi görünüyor.
akostadinov

2

Alabileceğimiz en doğru zaman damgası (en azından Mac OS X için) muhtemelen şu şekildedir:

python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'

1490665305.021699

Ancak, yayınlanmasının yaklaşık 30 milisaniye sürdüğünü unutmayın. 2 basamaklı kesir ölçeğine kadar kesebiliriz ve en başında zamanı okumanın ortalama ek yükünü hesaplayabilir ve ölçümden kaldırabiliriz. İşte bir örnek:

function getTimestamp {
  echo `python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")' | cut -b1-13` 
}
function getDiff {
  echo "$2-$1-$MeasuringCost" | bc
}
prev_a=`getTimestamp`
acc=0
ITERATIONS=30
for i in `seq 1 $ITERATIONS`;do 
  #echo -n $i 
  a=`getTimestamp`
  #echo -n "   $a"
  b=`echo "$a-$prev_a" | bc`
  prev_a=$a
  #echo "  diff=$b"
  acc=`echo "$acc+$b" | bc`
done
MeasuringCost=`echo "scale=2; $acc/$ITERATIONS" | bc`
echo "average: $MeasuringCost sec"
t1=`getTimestamp`
sleep 2
t2=`getTimestamp`
echo "measured seconds: `getDiff $t1 $t2`"

Nasıl çalıştığını daha iyi görmek için yankı komutlarını açabilirsiniz.

Bu betiğin sonuçları genellikle şu 3 sonuçtan biridir:

measured seconds: 1.99
measured seconds: 2.00
measured seconds: 2.01

1

Date ve expr kullanmak sizi oraya götürebilir.

X=$(expr \`date +%H\` \\* 3600 + \`date +%M\` \\* 60 + \`date +%S\`)
echo $X

Sadece ne istersen onu yap.

Bunun, çağdan beri milisaniye vermediğini fark ettim, ancak bazı durumlarda cevap olarak hala yararlı olabilir, hepsi için neye ihtiyaç duyduğunuza bağlı olarak, bir milisaniye sayısına ihtiyacınız varsa, 1000 ile çarpın: D

En basit yöntem, küçük bir çalıştırılabilir yapmak (Cf.ex. den) ve betiğin kullanımına sunmaktır.


dateBirden çok kez çalışan potansiyel bir sorun var . Bazı durumlarda, tarih veya saat komutunuz yazıldıkça çalıştırmalar arasında değişebilir. Bir datekere kaçıp parçalarını parçalayıp hesaplarını yapmak daha iyi olur . Bunu yapmanın birkaç yolundan biri olurdu t=$(date +%H%M%S); (( x = ${t:0:2} * 3600 + ${t:2:2} * 60 + ${t:4:2} )); echo "$x". Bu soru bash olarak etiketlendiğinden Bash sözdizimini kullanır . Sizlerin aldattığınız gibi, cevabınız (ve varyasyonum) değirmende değil, Epoch'tan bu yana değil, şimdiki gün için yalnızca birkaç saniye verir.
Dennis Williamson,

1

(yukarıdan tekrarlayın) date +%NOS X üzerinde çalışmıyor, ancak şunları da kullanabilirsiniz:

Perl (Zaman :: Format modülü gerektirir). Muhtemelen kullanılabilecek en iyi CPAN modülü değildir, ancak işi yapar. Time :: Format genellikle dağıtımlarda kullanılabilir duruma gelir.

perl -w -e'use Time::Format; printf STDOUT ("%s.%s\n", time, $time{"mmm"})'

OP özellikle bash kullanarak bunu yapmanın yollarını istedi. Bu bash, başka bir şeyi başlatmak için bir yöntem olarak kaydetme nasıl?
MadHatter

Bunu OSX altındaki bash shell scriptlerimde kullanıyorum. Bu yüzden datekullanılamaz ve ihtiyaca cevap veren sadece bash komutları yoktur.
TVNshack

Yeterince adil. OSX’lerin neden cevabınızın bir parçasıdate olarak kullanılamadığını açıklamak isteseydiniz, oyumun altındaki oyu kaldırırdım.
MadHatter

Bu yukarıda birkaç cevap açıklanmıştır. Önerilen listeyle eksik olan bu komutu yorum olarak ekleyemedim. Bu yüzden buraya ekledim.
TVNshack

Yeterince adil, bu kanonun yararlı bir ek olduğunu kabul ediyorum. Benden +1!
MadHatter

1

OSX'deyken önceki yanıtları bir araya getirmek

ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G31+

beğenebilirsin

microtime() {
    python -c 'import time; print time.time()'
}
compute() {
    local START=$(microtime)
    #$1 is command $2 are args
    local END=$(microtime)
    DIFF=$(echo "$END - $START" | bc)
    echo "$1\t$2\t$DIFF"
}

0

Basit bir kabuk geçen hesaplama istiyorsanız, yukarıdaki cevabı kullanarak bu kolay ve taşınabilir:

now() {
    python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'
}
seismo:~$ x=`now`
seismo:~$ y=`now`
seismo:~$ echo "$y - $x" | bc
5.212514

0

Alp linux (birçok liman işçisi resmi) ve muhtemelen kötüye kullanabileceğiniz diğer minimal linux ortamları için adjtimex:

adjtimex | awk '/(time.tv_usec):/ { printf("%06d\n", $2) }' | head -c3

adjtimexçekirdek zaman değişkenlerini okumak (ve ayarlamak) için kullanılır. İle awkbirlikte size, mikrosaniye alabilirsiniz headsadece ilk 3 rakamını kullanabilirsiniz.

Bu komutun ne kadar güvenilir olduğu hakkında hiçbir fikrim yok.

Not: Bu cevaptan utanmadan çalındı

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.