ฉันจะใช้เวลาที่ผ่านไปในหน่วยมิลลิวินาทีใน Ruby ได้อย่างไร?


100

หากฉันมีTimeวัตถุที่ได้รับจาก:

Time.now

และต่อมาฉันก็สร้างอินสแตนซ์ออบเจ็กต์อื่นด้วยบรรทัดเดียวกันฉันจะดูได้อย่างไรว่าผ่านไปกี่มิลลิวินาทีแล้ว? วัตถุชิ้นที่สองอาจถูกสร้างขึ้นในนาทีเดียวกันในนาทีถัดไปหรือหลายชั่วโมง

คำตอบ:


136

ตามที่ระบุไว้แล้วคุณสามารถดำเนินการกับTimeวัตถุได้ราวกับว่าเป็นค่าตัวเลข (หรือทศนิยม) การดำเนินการเหล่านี้ทำให้เกิดความละเอียดที่สองซึ่งสามารถแปลงได้อย่างง่ายดาย

ตัวอย่างเช่น:

def time_diff_milli(start, finish)
   (finish - start) * 1000.0
end

t1 = Time.now
# arbitrary elapsed time
t2 = Time.now

msecs = time_diff_milli t1, t2

คุณจะต้องตัดสินใจว่าจะตัดทอนหรือไม่


2
เพิ่ม to_i และคุณมีเป็นจำนวนเต็มเช่น: ((จบ - เริ่ม) * 1000.0) .to_i
Travis Reeder

finish.to_f - start.to_fเหรอ?
ร่างกาย

1
finish - startให้จุดลอยตัว .to_fจะซ้ำซ้อน
ezpz

5
หากใช้รางหรือส่วนรองรับที่ใช้งานอยู่คุณสามารถใช้วิธี #in_milliseconds เพื่อทำการแปลงแบบเดียวกันได้(t2 - t1).in_milliseconds
Nathan Hanna

60

คุณสามารถเพิ่มน้ำตาลไวยากรณ์เล็กน้อยในโซลูชันข้างต้นโดยทำดังนี้:

class Time
  def to_ms
    (self.to_f * 1000.0).to_i
  end
end

start_time = Time.now
sleep(3)
end_time = Time.now
elapsed_time = end_time.to_ms - start_time.to_ms  # => 3004

31

ฉันคิดว่าคำตอบนั้นเลือกไม่ถูกต้องวิธีนั้นให้เวลาเป็นวินาทีไม่ใช่มิลลิวินาที

t = Time.now.t­o_f
=> 1382471965.146

ที่นี่ฉันคิดว่าค่าลอยตัวคือมิลลิวินาที


1
คำตอบที่เลือกถูกต้อง การใช้การบวกหรือการลบTime.nowจะถือว่าเวลาเป็นค่าจุดลอยตัวโดยมีวินาทีก่อนจุดทศนิยมและสูงถึงนาโนวินาทีหลังจุดทศนิยม (แม้ว่า nsec อาจไม่ถูกต้องสมบูรณ์ก็ตาม) ดังนั้นการคูณค่านั้นโดย1000.0ให้ผลเป็นมิลลิวินาที
dfherr

ใช่ แต่การให้แค่ "Time.now" นั้นไม่ถูกต้องและไม่ตอบคำถามได้อย่างแม่นยำ
LowFieldTheory

12

เพื่อให้ได้เวลาเป็นมิลลิวินาทีควรเพิ่ม.round(3)ดังนั้นในบางกรณีจะแม่นยำกว่า:

puts Time.now.to_f # => 1453402722.577573

(Time.now.to_f.round(3)*1000).to_i  # => 1453402722578

9

คำตอบของ ezpz เกือบจะสมบูรณ์แบบ แต่ฉันหวังว่าฉันจะสามารถเพิ่มได้อีกเล็กน้อย

Geo ถามเกี่ยวกับเวลาเป็นมิลลิวินาที ฟังดูเป็นปริมาณจำนวนเต็มและฉันจะไม่ใช้ทางอ้อมผ่านทางบก ดังนั้นแนวทางของฉันคือ:

irb(main):038:0> t8 = Time.now
=> Sun Nov 01 15:18:04 +0100 2009
irb(main):039:0> t9 = Time.now
=> Sun Nov 01 15:18:18 +0100 2009
irb(main):040:0> dif = t9 - t8
=> 13.940166
irb(main):041:0> (1000 * dif).to_i
=> 13940

การคูณด้วยจำนวนเต็ม 1000 จะรักษาจำนวนเศษส่วนได้อย่างสมบูรณ์แบบและอาจเร็วกว่าเล็กน้อยด้วย

หากคุณกำลังจัดการกับวันที่และเวลาคุณอาจต้องใช้คลาสDateTime นี้ทำงานคล้าย แต่ปัจจัยการแปลงเป็น 3600 * 24 * 1,000 = 86400000

ฉันพบว่าฟังก์ชันstrptimeและstrftimeของ DateTime มีค่าในการแยกวิเคราะห์และการจัดรูปแบบสตริงวันที่ / เวลา (เช่นถึง / จากบันทึก) สิ่งที่มีประโยชน์ที่ควรทราบคือ:

  • อักขระการจัดรูปแบบสำหรับฟังก์ชันเหล่านี้ (% H,% M,% S, ... ) เกือบจะเหมือนกับฟังก์ชัน C ที่พบในระบบ Unix / Linux ใด ๆ และ

  • ยังมีอีกสองสามประการ: โดยเฉพาะ% L เป็นมิลลิวินาที!


ดีแล้วที่รู้! ขอบคุณunknown:)
Geo

1
อย่างไรก็ตาม% L มีอยู่ใน Ruby 1.9 เท่านั้น)
Rafa de Castro

7

%L ให้ทับทิมเป็นมิลลิวินาที

require 'time'
puts Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L")

หรือ

puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")

จะให้เวลาปัจจุบันแก่คุณในหน่วยมิลลิวินาที


นี่ไม่ได้บอกว่าจะรับเวลาที่ผ่านไปได้อย่างไร
Robert

7
DateTime.now.strftime("%Q")

ตัวอย่างการใช้งาน:

>> DateTime.now.strftime("%Q")
=> "1541433332357"

>> DateTime.now.strftime("%Q").to_i
=> 1541433332357

6

Time.now.to_fสามารถช่วยคุณได้ แต่จะคืนค่าเป็นวินาที

โดยทั่วไปเมื่อทำงานกับเกณฑ์มาตรฐาน I:

  • ใส่ตัวแปรเวลาปัจจุบัน
  • แทรกบล็อกเพื่อทดสอบ
  • ใส่ตัวแปรเวลาปัจจุบันลบค่าเวลาปัจจุบันก่อนหน้า

เป็นกระบวนการที่ง่ายมากดังนั้นฉันไม่แน่ใจว่าคุณถามเรื่องนี้จริงๆ ...


4

คำตอบคือ:

t_start = Time.now
# time-consuming operation
t_end = Time.now

milliseconds = (t_start - t_end) * 1000.0

อย่างไรก็ตามTime.nowแนวทางดังกล่าวมีความเสี่ยงที่จะไม่ถูกต้อง ฉันพบโพสต์นี้โดย Luca Guidi:

https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/

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

ดังนั้นขอแนะนำให้ใช้Process.clock_gettimeแทน สิ่งที่ต้องการ:

def measure_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed_time = end_time - start_time
  elapsed_time.round(3)
end

ตัวอย่าง:

elapsed = measure_time do
    # your time-consuming task here:
    sleep 2.2321
end

=> 2.232

3

ลองลบ Time.now แรกออกจากครั้งที่สอง ชอบมาก:

a = Time.now
sleep(3)
puts Time.now - a # about 3.0

สิ่งนี้จะให้จำนวนทศนิยมของวินาทีระหว่างสองครั้ง (และด้วยจำนวนนั้นมิลลิวินาที)

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