จะรับเวลาปัจจุบันเป็นจำนวนเต็ม 13 หลักใน Ruby ได้อย่างไร?


88

ฉันมีjQueryฟังก์ชันนี้ที่คืนค่าเวลาปัจจุบันเป็นจำนวนมิลลิวินาทีนับตั้งแต่ยุค (1 ม.ค. 1970):

time = new Date().getTime();

มีวิธีทำเช่นเดียวกันใน Ruby หรือไม่?

ตอนนี้ฉันใช้ Ruby Time.now.to_iซึ่งใช้งานได้ดี แต่ส่งคืนจำนวนเต็ม10 หลัก (จำนวนวินาที)

ฉันจะให้มันแสดงจำนวนมิลลิวินาทีเหมือนเดิมได้jQueryอย่างไร?


5
นั่นไม่ใช่ "ฟังก์ชัน jQuery" แต่เป็นเพียง ECMAScript (javascript) ธรรมดา บางทีนั่นอาจเป็นสิ่งที่กระตุ้นให้ -1 ค่อนข้างรุนแรง
RobG

คำตอบ:


156
require 'date'

p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)

31
หมายเหตุสำหรับผู้ใช้ Rails: strftimeวิธีการที่จัดเตรียมโดยActiveSupport::TimeWithZoneไม่รวมถึง%sและตัว%Qระบุ คุณจะต้องแปลงเป็น Ruby ธรรมดาDateTimeก่อนโดยใช้to_datetimeวิธีนี้
Lonnon Foster

6
@LonnonFoster ตอนนี้ใช้งานได้แล้ว (เพิ่งทดสอบในคอนโซล Rails)
Nikola Stojaković

สวัสดีฉันจะทำสิ่งเดียวกันนี้ได้อย่างไร แต่ไม่ใช่ในตอนนี้ แต่จะทำจากช่องวันที่
Tomer

พบสิ่งนี้ที่นี่: stackoverflow.com/questions/24149463/ruby-strftimeq-broken
Tomer

โปรดทราบว่าสิ่งนี้จะตัดทอนแทนที่จะปัดเศษ (ดังที่คุณเห็นจากตัวอย่าง - 1384526946523ms ควรปัดเศษเป็น 1384526947s)
David Moles

102

Javascript gettime()ส่งคืนจำนวนมิลลิวินาทีนับตั้งแต่ยุค

รูบี้Time.now.to_iจะให้จำนวนวินาทีตั้งแต่ยุค หากคุณเปลี่ยนเป็นTime.now.to_fคุณจะยังคงได้รับวินาที แต่มีส่วนประกอบที่เป็นเศษส่วน เพียงแค่คูณมันด้วย 1,000 และคุณมีมิลลิวินาที จากนั้นใช้#to_iแปลงเป็นจำนวนเต็ม และคุณจะจบลงด้วย:

(Time.now.to_f * 1000).to_i

ขอบคุณมากสำหรับคำอธิบาย! ยังใหม่สำหรับสิ่งนี้ทั้งหมด ... ไม่รู้ว่าคำตอบใดที่จะทำเครื่องหมายว่าถูกต้องจริงๆ ...
ตินติน 81

1
สำหรับข้อมูลเพิ่มเติมTime.nowมาจาก Ruby เนื่องจากTime.currentมาจาก Rails ดังนั้นจึงTime.currentได้รับการยอมรับจากเขตเวลาแอปพลิเคชัน Rails และTime.nowกำลังใช้เขตเวลาของเซิร์ฟเวอร์ จากประสบการณ์ของฉันใช้Time.currentแอปพลิเคชัน Rails ของคุณเสมอเพื่อความสอดคล้องของเขตเวลา
vutran

1
ไม่คุณไม่ควรใช้Time.currentที่นี่เลยใช้เวลาสร้างนานกว่าและเนื่องจากคุณกำลังแปลงเป็นการประทับเวลายูนิกซ์ทันทีคุณจึงไม่สนใจเรื่องความสอดคล้องของเขตเวลาเลย (การประทับเวลา Unix เกี่ยวข้องกับ UTC เสมอ) ดังนั้นในขณะที่สิ่งที่คุณพูดเป็นความจริงใน 99% ของกรณีนี้ประสิทธิภาพที่ชาญฉลาดจะตกอยู่ใน 1% ที่ผ่านมา
The Pellmeister

1
นี่คือแนวทางที่ฉันต้องการ สิ่งหนึ่งที่ฉันชอบทำคือการเพิ่มคลาส Time เพื่อเพิ่ม:epochmethod: class Time def epoch (self.to_f * 1000) .to_i end end
Matt Welke

@brauliobo สนใจที่จะอธิบายอย่างละเอียดว่ามันปลอมเป็นมิลลิวินาทีได้อย่างไร? คำแถลงของคุณทำให้เข้าใจผิดคำตอบของ OP นั้นถูกต้อง
coisnepe

31

(Time.now.to_f * 1000).to_i ควรทำสิ่งเดียวกัน


1
@brauliobo มิลลิวินาทีปลอมคืออะไร?
Erik Rothoff

1
@brauliobo ไม่ได้เนื่องจากto_fรวมมิลลิวินาทีเป็นทศนิยม
CashIsClay

21

เมื่อใช้strftimeคุณจะได้รับจำนวนวินาทีและต่อท้ายมิลลิวินาทีเศษส่วน (หรือหน่วยที่เล็กกว่าหากจำเป็น):

2.2.2 :001 > t = Time.new
 => 2015-06-02 12:16:56 -0700 
2.2.2 :002 > t.strftime('%s%3N')
 => "1433272616888" 

โปรดทราบว่าสิ่งนี้จะไม่ปัดเศษ แต่จะตัดทอนอย่างที่คุณเห็นto_fหรือถ้าคุณออกไปเป็นไมโครวินาที:

2.2.2 :003 > t.to_f
 => 1433272616.888615
2.2.2 :004 > t.usec
 => 888615 

และto_f/ to_iโซลูชันมีปัญหาเดียวกัน:

2.2.2 :009 > (t.to_f * 1000).to_i
 => 1433272616888

ดังนั้นหากคุณจริงๆดูแลเกี่ยวกับความถูกต้องมิลลิวินาทีเดิมพันที่ดีกว่าอาจจะto_fมีround:

2.2.2 :010 > (t.to_f * 1000).round
 => 1433272616889

ดังที่ระบุไว้ในเอกสาร "IEEE 754 double ไม่แม่นยำพอที่จะแสดงจำนวนนาโนวินาทีตั้งแต่ยุค" ดังนั้นหากคุณสนใจจริงๆให้พิจารณาto_rแทนto_f-

2.2.2 :011 > (t.to_r * 1000).round
 => 1433272616889 

- แม้ว่าคุณจะปัดเศษเป็นมิลลิวินาทีคุณก็คงสบายดี


18

ระวังอย่าสับสน ความจริงที่ว่า Ruby สนับสนุนแนวคิดเรื่องเศษส่วนของวินาทีในการลอยตัวไม่ได้ทำให้เป็นจำนวนทศนิยม ฉันมีปัญหากับสิ่งนี้เมื่อฉันทำการเปรียบเทียบเวลาประทับเวลาของ Wireshark ใน Python ... การคำนวณเวลาใน pcap-ng ไม่ทำงาน ก็ต่อเมื่อฉันปฏิบัติกับทั้งสองส่วน (หนึ่งวินาทีและปริพันธ์นาโนวินาที) เนื่องจากจำนวนเต็มทั้งสองฉันสามารถหาตัวเลขที่เหมาะสมได้

ว่าตัวเลขจุดเพราะลอยมีปัญหาความถูกต้อง อันที่จริงรูบี้สั้น ๆ จะแสดงให้คุณเห็นว่า to_f ไม่เท่ากันพูด nsec:

irb(main):019:0> t=Time.now
=> 2015-04-10 16:41:35 -0500
irb(main):020:0> puts "#{t.to_f}; #{t.nsec}"
1428702095.1435847; 143584844

โปรแกรมเมอร์ Caveat คุณอาจปลอดภัยถึง 3 หลัก แต่ความจริงยังคงอยู่: ตัวเลขทศนิยมบนคอมพิวเตอร์เป็นค่าประมาณ ตัวนับนาโนวินาทีในคอมพิวเตอร์สมัยใหม่เป็นจำนวนเต็ม


การตอบสนองที่ดีขึ้น ขอขอบคุณ. รูปแบบคำสั่ง.strftime("%9N")ยังสามารถใช้ได้ ruby-doc.org/core-2.3.1/Time.html#method-i-strftime
rplaurindo

13

รับวัตถุTimeด้วยการTime.nowเรียก#to_iจะส่งคืนการประทับเวลา Unix (วินาทีจากยุค) #to_fให้เศษส่วนวินาทีที่คุณสามารถใช้เพื่อรับมิลลิวินาทีจากยุค:

Time.now.to_f * 1000

3
สิ่งนี้ปลอมเป็นมิลลิวินาที
brauliobo

@brauliobo นี่ "มิลลิวินาทีปลอม" ได้อย่างไร? คุณใช้เวลาในการรันโค้ดและตรวจสอบตัวเองหรือไม่?
coisnepe

0

จำนวนเต็ม typecast (1e6 * Time.now.to_f) ส่งคืน Bignum ที่สามารถเก็บค่ามิลลิวินาที

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