How to compare time in testing in Ruby on Rails
If microsecond precision is not required when testing Time, DateTime, or ActiveSupport::TimeWithZone, use iso8601 to assert equality between different times. There are two ways to avoid test failures caused by execution delays:
Use time.iso8601
Use time.to_fs(:iso8601)
For example, to compare two DateTime values maybe you can try to write it like this:
def test_question_answered_at_the_same_as_survey
assert_equal question.answered_at, survey.answered_at
end
describe 'question#answered_at'
it 'is the same as survey' do
expect(question.answered_at).to eq(survey.answered_at)
end
end
This approach can cause issues if there are microsecond delays when saving values to the database.
There are several ways to address this issue.
.changeOne option is to use .change to set microseconds to zero.
def test_question_answered_at_the_same_as_survey
assert_equal question.answered_at.change(usec: 0), survey.answered_at.change(usec: 0)
end
describe 'question#answered_at'
it 'is the same as survey' do
expect(question.answered_at.change(usec: 0)).to eq(survey.answered_at.change(usec: 0))
end
end
.to_iAlternatively, you can use the Time#to_i method, which truncates subseconds:
def test_question_answered_at_the_same_as_survey
assert_equal question.answered_at.to_i, survey.answered_at.to_i
end
describe 'question#answered_at'
it 'is the same as survey' do
expect(question.answered_at.to_i).to eq(survey.answered_at.to_i)
end
end
.roundYou can use from Ruby the Time#round where you can specific how to round the seconds value and doing Time#round is equivalent to Time#round(0) that means without milliseconds:
def test_answer_filled_at_the_same_as_survey
assert_equal(
question.answered_at.round,
survey.answered_at.round
)
end
describe 'question#answered_at' do
it 'is the same as survey' do
expect(
question.answered_at.round
).to eq(survey.answered_at.round
end
end
be_withinIn RSpec there is a specific helper called be_within which will convert Time to float and then check if the value is within a delta:
describe 'question#answered_at' do
it 'is the same as survey' do
expect(question.answered_at.round).to be_within(1).of(survey.answered_at)
end
end
assert_in_deltaA similar helper exists in Minitest called assert_in_delta that also transforms to float and then compare it if it is withing a delta:
def test_answer_filled_at_the_same_as_survey
assert_in_delta(
question.answered_at,
survey.answered_at,
1.0
)
end
.iso8601I recommend using iso8601 for this comparison:
def test_question_answered_at_the_same_as_survey
assert_equal question.answered_at.iso8601, survey.answered_at.iso8601
end
describe 'question#answered_at'
it 'is the same as survey' do
expect(question.answered_at.iso8601).to eq(survey.answered_at.iso8601)
end
end
In Rails, you can also use to_fs(:iso8601):
def test_question_answered_at_the_same_as_survey
assert_equal question.answered_at.to_fs(:iso8601), survey.answered_at.to_fs(:iso8601)
end
describe 'question#answered_at'
it 'is the same as survey' do
expect(question.answered_at.to_fs(:iso8601)).to eq(survey.answered_at.to_fs(:iso8601))
end
end
First, ISO8601 is a widely adopted standard, so its behavior is consistent across Ruby and Rails implementations.
Second, using time.iso8601 is more descriptive than time.change(usec: 0), making the comparison method clearer and supporting consistent conventions in the codebase.
Third, this approach allows you to compare with fixed time values as well:
assert_equal question.answered_at.iso8601, "2025-10-07T13:35:25+03:00"
expect(question.answered_at.iso8601).to eq "2025-10-07T13:35:25+03:00"
I know that someone might say well to understand what iso8601 does tyou have to know about it. But here I think it is a normal expectation for an web engineer to know about ISO8601 standard when working with time.
Of course you should choose the one that works best for you.
👉 If you like this article and want it in your inbox each week, subscribe to my newsletter. You’ll find ideas on Ruby, software development, software testing, building products and workshops, plus notes on creativity, tech trends, and whatever else sparks my curiosity.
👐 Want to improve your developer testing skills? Visit goodenoughtesting.com/articles to discover resources on testing for developers.
👉 Join my Short Ruby Newsletter for weekly Ruby updates and visit rubyandrails.info, a directory of Ruby learning content.
🤝 Connect with me on Linkedin, Bluesky, Ruby.social, , and Twitter, where I mostly post about Ruby and Ruby on Rails.
🎥 Follow my YouTube channel for short videos about Ruby and Rails.