วิธีรับเวลา Unix ปัจจุบันเป็นมิลลิวินาทีใน bash


232

ฉันจะได้รับเวลา Unix ปัจจุบันเป็นมิลลิวินาที (เช่นจำนวนมิลลิวินาทีตั้งแต่ Unix epoch 1 มกราคม 1970)

คำตอบ:


264

นี้:

date +%s 

จะกลับจำนวนวินาทีตั้งแต่ยุค

นี้:

date +%s%N

ส่งคืนวินาทีและนาโนวินาทีปัจจุบัน

ดังนั้น:

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

จะให้จำนวนมิลลิวินาทีแก่คุณตั้งแต่วินาที - วินาทีปัจจุบันบวกสามวินาทีที่เหลือ


และจากMikeyB - echo $(($(date +%s%N)/1000000))(หารด้วย 1,000 นำไปสู่ ​​microseconds เท่านั้น)


39
ฉันสงสัยว่า ms ตัดเพิ่ม :-) กี่เครื่อง
Kyle Brandt

13
หรือถ้าคุณต้องการที่จะทำทั้งหมดในเปลือกหลีกเลี่ยงค่าใช้จ่ายแพงของกระบวนการเพิ่มเติม (อันที่จริงเรากำลังหลีกเลี่ยงปัญหาเมื่อจำนวนของตัวเลขในการเปลี่ยนแปลง% + s + N):echo $(($(date +%s%N)/1000))
MikeyB

5
มันเป็นหลักการของเรื่อง ... หลีกเลี่ยงหมายเลขมายากลและรหัสสิ่งที่คุณจริงหมายถึง
MikeyB

25
ฉันคิดว่ามันน่าสังเกตว่าชายคนนั้นถาม Unix ไม่ใช่ Linux และคำตอบยอดนิยมปัจจุบัน (date +% s% N) ไม่ทำงานบนระบบ AIX ของฉัน
Pete

12
@Pete +1 เหมือนกันสำหรับ OS X และ FreeBSD
ocodo

99

คุณสามารถใช้%3Nเพื่อตัดทอน nanoseconds เป็นตัวเลขที่สำคัญที่สุด 3 ตัว (ซึ่งก็คือมิลลิวินาที):

$ date +%s%3N
1397392146866

มันทำงานได้เช่นใน kubuntu 12.04 ของฉัน

แต่ระวังว่า%Nอาจไม่สามารถใช้งานได้ขึ้นอยู่กับระบบเป้าหมายของคุณ เช่นการทดสอบในระบบฝังตัว (build รูท rootfs รวบรวมโดยใช้ toolchain แขนที่ไม่ใช่ HF) ไม่มี%N:

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

(และแท็บเล็ต Android ของฉัน (ไม่รูท) ไม่มีเลย%N)


1
@warren: ผมเห็นว่าคุณแก้ไขและเปลี่ยนแปลง1397392146%3Nไป1397392146%Nแต่การส่งออกของ1397392146%3Nนั่นคือสิ่งที่ฉันต้องการเห็นจริงๆบนคอนโซล busybox ของแท็บเล็ต Android ของฉัน คุณช่วยอธิบายการแก้ไขของคุณได้ไหม?
Joe

ความคิดเห็นของวอร์เรนจากประวัติศาสตร์คือ "เปลี่ยนจาก 3 เป็น 6 เนื่องจาก 3 นำคุณไปสู่ไมโครวินาทีเท่านั้น" การแก้ไขของเขาดูเหมือนปลอมทั้งหมด คุณควรย้อนกลับ
bukzor

1
นี่เป็นคุณสมบัติของ coreutils GNU โดยเฉพาะ ท้ายที่สุดนี้จะดำเนินการใน gnulib ที่นี่: github.com/gagern/gnulib/blob/...
telotortium

อาจเป็นจุดในนั้นทำให้รู้สึก พิมพ์date +%s.%3N 1510718281.134
darksky

นี่ควรเป็นคำตอบที่ยอมรับได้
Noah Sussman

61

date +%N ไม่ทำงานบน OS X แต่คุณสามารถใช้อย่างใดอย่างหนึ่ง

  • ทับทิม: ruby -e 'puts Time.now.to_f'
  • หลาม: python -c 'import time; print time.time()'
  • Node.js: node -e 'console.log(Date.now())'
  • PHP: php -r 'echo microtime(TRUE);'
  • ยาอายุวัฒนะ: DateTime.utc_now() |> DateTime.to_unix(:millisecond)
  • internets: wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
  • หรือเป็นมิลลิวินาทีที่ปัดเศษเป็นวินาทีที่ใกล้ที่สุด date +%s000

1
เพื่อความสมบูรณ์ ...node -e 'console.log(Date.now())'
slf

1
ใช้ PHP:php -r 'echo microtime(TRUE);'
TachyonVortex

8
แน่นอนว่าคุณต้องรอให้ล่ามเหล่านั้นอุ่นขึ้น งานนี้ด้วย:wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
Camilo Martin

8
หรือถ้าคุณไม่จริงต้องมิลลิวินาทีแต่เพียงรูปแบบที่ถูกต้อง:date +%s000
Lenar ฮอยต์

1
apple.stackexchange.com/questions/135742/…มีคำแนะนำสำหรับการทำสิ่งนี้ใน OSX ผ่านทาง Brew'scoreutils
sameers

9

แค่โยนนี่ออกไป แต่ฉันคิดว่าสูตรที่ถูกต้องกับการแบ่งจะเป็น:

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

9

วิธีแก้ปัญหาของฉันไม่ดีที่สุด แต่ใช้ได้สำหรับฉัน

date +%s000

ฉันต้องการแปลงวันที่อย่าง 2012-05-05 เป็นมิลลิวินาที


1
แฮ็คที่น่าอัศจรรย์ฮ่า ๆ :)
k06a

7
คุณต้องเป็นคนหนึ่งในหมู่เพื่อนร่วมงานของฉัน
Nakilon

7

สำหรับผู้ที่แนะนำให้เรียกใช้โปรแกรมภายนอกเพื่อรับมิลลิวินาที ... ในอัตรานั้นคุณอาจทำเช่นนี้:

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

จุดคือ: ก่อนที่จะเลือกคำตอบใด ๆ จากที่นี่โปรดทราบว่าไม่ใช่ว่าทุกโปรแกรมจะทำงานภายในหนึ่งวินาที วัด!


คุณไม่ได้ขอให้ระบบในพื้นที่นั้น ซึ่งฉันเดาว่าส่อให้เห็นในคำถาม คุณยังต้องพึ่งพาการเชื่อมต่อเครือข่าย
orkoden

2
@orkoden คำถามที่ถามอย่างชัดเจน "จำนวนมิลลิวินาทีตั้งแต่ Unix ยุค 1 มกราคม 1970" นอกจากนี้ฉันยังชี้ให้เห็นว่าคุณไม่ควรลุกขึ้นทั้ง Ruby หรือ Python (หรือ wget) เพียงเพื่อให้ได้เวลา - สิ่งนี้ทำได้ผ่านช่องทางที่รวดเร็วหรือมิลลิวินาทีไม่สำคัญ
Camilo Martin

2
ใช่ฉันเข้าใจว่าคุณกำลังให้วิธีแก้ปัญหาที่แย่กว่านั้นเพื่อเน้นข้อบกพร่องของโซลูชัน ฉันลองวิธีแก้ปัญหาหลายอย่างและวัดเวลา lpaste.net/119499ผลลัพธ์น่าสนใจ แม้แต่ในเครื่องที่เร็วมาก i7 dateก็ใช้เวลา 3 ms ในการทำงาน
orkoden

@orkoden การทดสอบที่ดี! ระบบปฏิบัติการอะไร สิ่งนี้อาจเกี่ยวข้องกับกระบวนการที่วางไข่เหนือศีรษะ
Camilo Martin

1
@Nakilon และนี่คือเหตุผลว่าทำไมไม่ควรพึ่งพาสิ่งอำนวยความสะดวกแบบขดได้อย่างที่ต้องการสำหรับการผลิตทุกอย่าง
Camilo Martin

4

วิธีนี้ใช้ได้กับ macOS

หากคุณพิจารณาใช้สคริปต์ทุบตีและมีไพ ธ อนอยู่คุณสามารถใช้รหัสนี้ได้:

#!/bin/bash

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

ทำไมลงคะแนน?
Frank Thonig

ดูเหมือนจะไม่เป็นธรรมโดยเฉพาะ คำใบ้บนลูกศรลงบอกว่า "คำตอบนี้ไม่มีประโยชน์" แต่ IMO ก็มีประโยชน์ บางทีพวกเขาต้องการให้คุณสร้างเป็นสคริปต์ Python แทน ที่จะง่ายขึ้นและยังทำงานได้ดีเป็นคำสั่ง bash
Andrew Schulman

ไม่ต้องกังวลมากเกินไปเกี่ยวกับ downvotes (ไม่ใช่ของฉัน) ... โดยเฉพาะอย่างยิ่งถ้าพวกเขาไม่ระบุชื่อ เพียงเพื่อซ่อนคุณดำเนินการ ... ไปที่นี่อีก +1 ... เดาว่า: คุณได้รับอนุญาตให้ "ลงคะแนน" ตอนนี้ใช่ไหม?
Pierre.Vriens

Downvote ดูเหมือนว่ามีสาเหตุมาจากปัญหากับระบบ มันถูกลบตั้งแต่นั้นอีกครั้งโดยระบบ
Michael Hampton

2

หากคุณกำลังมองหาวิธีที่จะแสดงระยะเวลาที่สคริปต์ของคุณทำงานอยู่ข้อมูลต่อไปนี้จะให้ผลลัพธ์ (ไม่แม่นยำอย่างสมบูรณ์):

ใกล้ถึงจุดเริ่มต้นของสคริปต์ของคุณให้ป้อนต่อไปนี้

basetime=$(date +%s%N)

นี่จะให้ค่าเริ่มต้นของบางอย่างเช่น 1361802943996000000 ของคุณ

ในตอนท้ายของสคริปต์ของคุณใช้ต่อไปนี้

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

ซึ่งจะแสดงสิ่งที่ชอบ

runtime: 12.383 seconds

หมายเหตุ:

(1 * 10 ^ 09) สามารถถูกแทนที่ด้วย 1000000000 ถ้าคุณต้องการ

"scale=3"เป็นการตั้งค่าที่ค่อนข้างหายากที่ coerces ที่bcจะทำสิ่งที่คุณต้องการ มีอีกมากมาย!

ฉันทดสอบสิ่งนี้บน Win7 / MinGW เท่านั้น ... ฉันไม่มีกล่อง * * * * ที่ถูกต้อง


3
หรือคุณสามารถใช้time <script>
วอร์เรน

2

นี่คือวิธีรับเวลาเป็นมิลลิวินาทีโดยไม่ต้องทำการหาร อาจจะเร็วกว่า ...

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

อัปเดต: อีกทางเลือกหนึ่งในการทุบตีบริสุทธิ์ที่ใช้ได้เฉพาะกับbash 4.2+เหมือนข้างต้น แต่ใช้printfเพื่อรับวันที่ มันจะเร็วขึ้นแน่นอนเพราะไม่มีกระบวนการใดแยกออกจากกระบวนการหลัก

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

อีกสิ่งหนึ่งที่strftimeควรพิจารณาคือการติดตั้งใช้งานของคุณควรรองรับ%sและ%Nไม่ใช่ในกรณีของเครื่องทดสอบของฉัน ดูman strftimeตัวเลือกที่รองรับ ดูman bashเพิ่มเติมที่printfไวยากรณ์ -1และ-2เป็นค่าพิเศษสำหรับเวลา


ดูเหมือนว่าฉันstrftime(3)ไม่ได้รับการสนับสนุน%Nดังนั้นจึงไม่มีทางที่printfจะพิมพ์นาโนวินาที ฉันใช้ Ubuntu 14.04
haridsv

@haridsv ใช่มันไม่ได้อยู่ใน glibc dateดูเหมือนว่าตัวเลือกที่เชื่อถือได้มากขึ้น
akostadinov

2

เวลาที่แม่นยำที่สุดที่เราจะได้รับ (อย่างน้อยสำหรับ Mac OS X) น่าจะเป็นสิ่งนี้:

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

1490665305.021699

แต่เราต้องจำไว้ว่าใช้เวลาประมาณ 30 มิลลิวินาทีในการทำงาน เราสามารถตัดให้เหลือเพียงเสี้ยว 2 หลักและในตอนเริ่มต้นคำนวณค่าใช้จ่ายโดยเฉลี่ยในการอ่านเวลาแล้วลบออกจากการวัด นี่คือตัวอย่าง:

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`"

คุณสามารถยกเลิกการคอมเม้นท์คำสั่ง echo เพื่อดูว่ามันทำงานอย่างไร

ผลลัพธ์สำหรับสคริปต์นี้มักจะเป็นหนึ่งใน 3 ผลลัพธ์เหล่านี้:

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

1

การใช้วันที่และ expr ช่วยให้คุณไปถึงที่นั่นได้

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

เพียงขยายเพื่อทำสิ่งที่คุณต้องการ

ฉันรู้ว่านี่ไม่ได้ให้มิลลิวินาทีตั้งแต่ยุค แต่มันอาจจะมีประโยชน์เป็นคำตอบสำหรับบางกรณีมันทั้งหมดขึ้นอยู่กับสิ่งที่คุณต้องการจริงๆคูณด้วย 1,000 ถ้าคุณต้องการจำนวนมิลลิวินาที: D

วิธีที่ง่ายที่สุดคือทำให้ไฟล์เล็ก ๆ (จาก C f.ex. ) และทำให้สคริปต์นั้นพร้อมใช้งาน


มีปัญหาที่อาจเกิดขึ้นในการทำงานdateหลายครั้ง ในบางกรณีวันที่หรือเวลาอาจมีการเปลี่ยนแปลงระหว่างการรันตามคำสั่งของคุณ จะดีกว่าถ้าใช้dateครั้งเดียวแล้วแยกส่วนและทำการคำนวณของคุณ หนึ่งในหลายวิธีที่จะทำเช่นนั้นt=$(date +%H%M%S); (( x = ${t:0:2} * 3600 + ${t:2:2} * 60 + ${t:4:2} )); echo "$x"คือ นี้ใช้ไวยากรณ์ทุบตีตั้งแต่คำถามที่ถูกแท็กทุบตี ในขณะที่คุณพูดถึงคำตอบของคุณ (และรูปแบบของฉัน) ให้เวลาเพียงไม่กี่วินาทีสำหรับวันปัจจุบันจนถึงขณะนี้ไม่ใช่ตั้งแต่ยุคและไม่ใช่มิลลิวินาที
Dennis Williamson

1

(ทำซ้ำจากด้านบน) date +%Nไม่ทำงานบน OS X แต่คุณสามารถใช้:

Perl (ต้องใช้เวลา :: รูปแบบโมดูล) อาจไม่ใช่โมดูล CPAN ที่ดีที่สุดที่จะใช้ แต่ทำงานได้สำเร็จ เวลา :: รูปแบบโดยทั่วไปแล้วจะมีให้พร้อมกับการแจกแจง

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

OP ขอเฉพาะวิธีที่จะทำโดยใช้ bash ทุบตีนี้เป็นวิธีการบันทึกเป็นวิธีการเปิดอย่างอื่นได้อย่างไร
MadHatter

ฉันใช้สิ่งนี้ในสคริปต์ทุบตีเชลล์ของฉัน ... ภายใต้ OSX ดังนั้นdateไม่สามารถใช้งานได้และไม่มีคำสั่ง bash-only ที่ตอบสนองความต้องการ
TVNshack

ยุติธรรมพอสมควร หากคุณต้องชี้แจงว่าทำไม OSX dateไม่สามารถใช้เป็นส่วนหนึ่งของคำตอบของคุณได้ฉันจะลบ downvote ของฉันออก
MadHatter

คำอธิบายนี้มีคำตอบสองสามข้อด้านบน ฉันไม่สามารถเพิ่มเป็นความคิดเห็นคำสั่งที่หายไปกับรายการที่เสนอ ดังนั้นฉันได้เพิ่มที่นี่
TVNshack

ยุติธรรมพอฉันยอมรับว่านี่เป็นส่วนเสริมที่มีประโยชน์สำหรับแคนนอน +1 จากฉัน!
MadHatter

1

รวบรวมคำตอบก่อนหน้านี้ทั้งหมดไว้ด้วยกันเมื่ออยู่ใน OSX

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

คุณสามารถทำเช่นนั้น

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

หากคุณต้องการการคำนวณแบบเชลล์ที่เรียบง่ายนี่เป็นเรื่องง่ายและพกพาโดยใช้คำตอบข้างต้น:

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

สำหรับอัลไพน์ลินุกซ์ (ภาพนักเทียบท่าจำนวนมาก) และสภาพแวดล้อมลินุกซ์ขั้นต่ำอื่น ๆ ที่คุณอาจใช้ในทางที่ผิดadjtimex:

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

adjtimexถูกใช้เพื่ออ่าน (และตั้งค่า) ตัวแปรเวลาเคอร์เนล ด้วยawkคุณสามารถรับไมโครวินาทีโดยheadคุณสามารถใช้ตัวเลข 3 ตัวแรกเท่านั้น

ฉันไม่รู้ว่าคำสั่งนี้เชื่อถือได้แค่ไหน

หมายเหตุ: ถูกขโมยไปอย่างไร้รอยต่อจากคำตอบนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.