visit our site

Time comparison in Ruby

In Development

by Olexander Paladiy by April 1, 2014

I believe every ruby developer has faced time comparison issue at least once and tests are one of the possible areas where it may happen. RSpec message like this may confuse:

What’s wrong?


Let’s create two Time objects:

At the first glance, they are equal. But it’s not true:

The issue occurs because ruby Time makes comparison with fractions of seconds. We may use to_f method to see the difference between t1 and t2:

or to_r method to get rational numbers:


If you don’t care about milliseconds, you may compare timestamps using to_i method:

or make a new Time object from timestamps to have better RSpec failure messages:

But even better to use fixed times in our tests.

* Railsware is a premium software development consulting company, focused on delivering great web and mobile applications. Learn more about us.
  • Maxime Garcia

    Or instead of rounding to the second, you embrace a difference of less a second :
    expect(t1).to be_within(1.second).of(t2)

    • 1.second is from ActiveSupport, so this will not work in plain old Ruby.

      I prefer to use the technique Lionel mentioned above, just nicely format the time and then compare strings.

      RSpec::Matchers.define :be_the_same_time_as do |expected|
      match do |actual|
      expect(expected.strftime("%d-%m-%Y %H:%M:%S")).to eq(actual.strftime("%d-%m-%Y %H:%M:%S"))

      describe "time comparison" do
      it "passes for equal time" do

      expect( be_the_same_time_as

      • irb(main):001:0> t1 =
        => 2014-04-14 23:08:45 +0200
        irb(main):002:0> t1.to_f
        => 1397509725.5656137
        irb(main):003:0> – t1
        => 12.845386198

        As be_within matcher works with the minus function :
        expect(t1).to be_within(1).of(t2)

        The “.second” is not necessary.

  • Lionel Tan

    Great explanation and solution to how to solve Time comparisons.

    I used to do it by casting it to a string like below:

    a, b =,

    a_to_s = a.strftime(‘%Y-%m-%d %H:%M:%S’)
    b_to_s = b.strftime(‘%Y-%m-%d %H:%M:%S’)

    a_to_s == b_to_s

  • You may do the following (assuming t1 and t2 are Time instances)

    require 'date'

    t1.to_date == t2.to_date

  • Ahmad hamza

    Hi i m comparing time like this “if a.start_time<= client.start" but a.start_time has the value "1970-01-01 09:00:00 UTC" and "2000-01-01 09:00:00 UTC". How to change that a.start_time ? Any idea

  • Aleksandr Kunin

    Or just use t1.round, that by default (without arguments) returns new Time object without subseconds.

Signup for our weekly newsletter

Want to get more of Railsware blog?

RSS Feed

We're always ready to help!

Contact us