วิธีรับมิลลิวินาทีตั้งแต่ Unix ยุค


30

ฉันต้องการสคริปต์ทุบตีที่วัดเวลาเปิดตัวของเบราว์เซอร์สำหรับที่ฉันใช้ html ซึ่งได้รับการประทับเวลาโหลดเป็นมิลลิวินาทีโดยใช้ JavaScript

ในเชลล์สคริปต์ก่อนที่ฉันจะเรียกเบราว์เซอร์ฉันได้รับการประทับเวลาด้วย:

date +%s

ปัญหาคือว่ามันได้รับการประทับเวลาในไม่กี่วินาทีและฉันต้องการมันเป็นมิลลิวินาทีเพราะบางครั้งเมื่อวิ่งครั้งที่สองเบราว์เซอร์เริ่มในไม่กี่วินาทีและฉันต้องสามารถวัดเวลาได้อย่างแม่นยำโดยใช้มิลลิวินาทีแทนวินาที

ฉันจะรับการประทับเวลาเป็นมิลลิวินาทีจากสคริปต์ทุบตีได้อย่างไร

คำตอบ:


28

date +%s.%Nจะให้เช่น1364391019.877418748.. % N คือจำนวนนาโนวินาทีที่ผ่านไปในวินาทีปัจจุบัน แจ้งให้ทราบล่วงหน้ามันเป็น 9 หลักและแผ่นเริ่มต้นวันนี้จะด้วยศูนย์ถ้ามันเป็นน้อยกว่า 100000000 นี้เป็นจริงปัญหาถ้าเราต้องการที่จะทำคณิตศาสตร์ที่มีจำนวนเพราะตัวเลขทุบตีถือว่ามีศูนย์นำเป็นฐานแปด ช่องว่างภายในนี้สามารถปิดการใช้งานโดยใช้เครื่องหมายขีดกลางในข้อมูลจำเพาะของสนามดังนั้น:

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

จะไร้เดียงสาให้มิลลิวินาทีตั้งแต่ยุค

อย่างไรก็ตามในขณะที่สเตฟานชาซาลาสชี้ให้เห็นในความคิดเห็นด้านล่างนั่นคือการdateโทรที่แตกต่างกันสองสายซึ่งจะให้ผลสองครั้งที่แตกต่างกันเล็กน้อย หากที่สองมีการย้อนกลับไปในระหว่างพวกเขาการคำนวณจะเป็นทั้งสองออก ดังนั้น:

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

หรือปรับให้เหมาะสม (ขอบคุณสำหรับความคิดเห็นด้านล่างแม้ว่าสิ่งนี้ควรจะชัดเจน):

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

ฉันลองแล้วมันใช้งานได้ขอบคุณ +1 / ยอมรับ!
Eduard Florinescu

7
โปรดทราบว่าในระหว่างเวลาที่คุณเรียกใช้วันที่แรกและวันที่ที่สองหลายล้าน nanoseconds อาจผ่านไปแล้วและอาจไม่ได้เป็นวินาทีเดียวกัน $(($(date +'%s * 1000 + %N / 1000000')))ที่ดีที่สุดที่จะทำ ที่ยังไม่สมเหตุสมผล แต่จะเชื่อถือได้มากขึ้น
Stéphane Chazelas

1
แก้ไขโดยการปิดการเติมศูนย์ตามที่ระบุไว้ในวันที่ (1)
Alois Mahdal

3
%Nไม่สามารถใช้งานได้ใน BSD และ OS X
orkoden

1
ทำไมไม่เพียงecho $(( $(date '+%s%N') / 1000000))?
Hitechcomputergeek

47

ด้วย GNU หรือการใช้งานแบบเปิดdate(หรือ busybox 'หากสร้างโดยFEATURE_DATE_NANOเปิดใช้งานตัวเลือก) ฉันจะใช้:

$ date +%s%3N

ซึ่งจะส่งคืนมิลลิวินาทีนับตั้งแต่ยุค Unix


5
สง่างามน่ารัก +1
Eduard Florinescu

1
การถอนเงินเพื่อความสง่างาม
sleepycal

สง่างามแน่นอน +1 ถ้าชอบฉันคุณต้องการให้แน่ใจว่า%3Nมีการเติมเต็มสิ่งที่จำเป็นเป็นศูนย์ (โดยไม่ต้องอ่านเอกสาร. ;-) คุณสามารถทำได้while sleep 0.05; do date +%s%3N; doneและใช่มีศูนย์ที่จำเป็นอยู่
เทอร์รี่บราวน์

ขอบคุณเทอร์รี่! อย่างไรก็ตาม%3Nเป็นศูนย์เบาะแน่นอน นอกจากนี้ฉันไม่คิดว่าวิธีแก้ปัญหาของคุณจะเพิ่มศูนย์เพียงแค่ชะลอการตอบสนองน้อยมาก
javabeangrinder

javabeangrinder, รหัสของ @ TerryBrown ไม่ใช่วิธีแก้ปัญหา , เพียงแค่ทดสอบรหัสเพื่อตรวจสอบว่า%3Nเป็นแบบ 0-padded
Stéphane Chazelas

10

ในกรณีที่คนจะใช้เปลือกหอยอื่น ๆ กว่าbash, ksh93และzshมีจุดลอย$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

หมายเหตุว่าของที่ได้มาจากจำนวนเต็มสองจำนวน (ต่อวินาทีและนาโนวินาที) clock_gettime()ส่งกลับโดย ในระบบส่วนใหญ่นั้นมีความแม่นยำมากกว่าdoubleตัวเลขจุดลอยตัวC เดียวดังนั้นคุณจะสูญเสียความแม่นยำเมื่อคุณใช้ในการแสดงออกทางคณิตศาสตร์ (ยกเว้นวันที่ในช่วงสองสามเดือนแรกของปี 1970)

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

ในการคำนวณความแตกต่างของเวลาที่มีความแม่นยำสูง (แม้ว่าฉันสงสัยว่าคุณต้องการความแม่นยำมากกว่ามิลลิวินาที) คุณอาจต้องการใช้$epochtimeอาร์เรย์พิเศษแทน (ซึ่งมีวินาทีและนาโนวินาทีเป็นองค์ประกอบแยกสองส่วน)

ตั้งแต่รุ่น 5.7 (2018) strftimeเชลล์ builtin ยังสนับสนุน%Nรูปแบบ nanosecond à la GNU dateและ a %.เพื่อระบุความแม่นยำดังนั้นจำนวนมิลลิวินาทีนับตั้งแต่ยุคสามารถดึงได้ด้วย:

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

(หรือเก็บไว้ในตัวแปรด้วย-s var)


โปรดทราบว่าตัวแปร "$ SECONDS" ไม่ได้เชื่อมต่อ / เกี่ยวข้องกับเวลายุค ส่วนที่เป็นเศษส่วน (มิลลิวินาทีไมโครวินาทีและนาโนวินาที) อาจแตกต่างกันไปในแต่ละส่วน
ไอแซค

8

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

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

ในทุบตี 5+ $EPOCHREALTIMEมีตัวแปรที่มีขนาดเล็กสองเมล็ด:

ดังนั้น:

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

พิมพ์เวลาตั้งแต่ยุค (1/1/70) ในหน่วยมิลลิวินาที

ความล้มเหลวนั้นคุณต้องใช้วันที่ อาจเป็นวันที่ GNU:

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

ทางเลือกหนึ่งที่อยู่ในรายการhttps://serverfault.com/a/423642/465827

หรือbrew install coreutilsสำหรับ OS X

หรือหากทุกอย่างล้มเหลวให้คอมไพล์ (gcc epochInµsec.c) โปรแกรม 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.