[ruby] How do I get elapsed time in milliseconds in Ruby?

If I have a Time object got from :

Time.now

and later I instantiate another object with that same line, how can I see how many milliseconds have passed? The second object may be created that same minute, over the next minutes or even hours.

This question is related to ruby

The answer is


DateTime.now.strftime("%Q")

Example usage:

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

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

Time.now.to_f can help you but it returns seconds.

In general, when working with benchmarks I:

  • put in variable the current time;
  • insert the block to test;
  • put in a variable the current time, subtracting the preceding current-time value;

It's a very simple process, so I'm not sure you were really asking this...


Try subtracting the first Time.now from the second. Like so:

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

This gives you a floating-point number of the seconds between the two times (and with that, the milliseconds).


To get time in milliseconds, it's better to add .round(3), so it will be more accurate in some cases:

puts Time.now.to_f # => 1453402722.577573

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

%L gives milliseconds in ruby

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

or

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

will give you current timestamp in milliseconds.


ezpz's answer is almost perfect, but I hope I can add a little more.

Geo asked about time in milliseconds; this sounds like an integer quantity, and I wouldn't take the detour through floating-point land. Thus my approach would be:

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

Multiplying by an integer 1000 preserves the fractional number perfectly and may be a little faster too.

If you're dealing with dates and times, you may need to use the DateTime class. This works similarly but the conversion factor is 24 * 3600 * 1000 = 86400000 .

I've found DateTime's strptime and strftime functions invaluable in parsing and formatting date/time strings (e.g. to/from logs). What comes in handy to know is:

  • The formatting characters for these functions (%H, %M, %S, ...) are almost the same as for the C functions found on any Unix/Linux system; and

  • There are a few more: In particular, %L does milliseconds!


You can add a little syntax sugar to the above solution with the following:

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

I think the answer is incorrectly chosen, that method gives seconds, not milliseconds.

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

Here I suppose the floating value are the milliseconds


The answer is something like:

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

milliseconds = (t_start - t_end) * 1000.0

However, the Time.now approach risks to be inaccurate. I found this post by Luca Guidi:

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

system clock is constantly floating and it doesn't move only forwards. If your calculation of elapsed time is based on it, you're very likely to run into calculation errors or even outages.

So, it is recommended to use Process.clock_gettime instead. Something like:

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

Example:

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

=> 2.232