Lorro
Lorro

Reputation: 88

Comparing datetime in Rails always false

I'm trying to compare two dates of which both are datetime.

closed_at and updated_at (while updated_at is the one already created by rails)

This is my code:

<% if @task.closed_at == @task.updated_at %>
    *Some stuff*
<% end %>

With closing a task it gets automatically updated.

irb(main):011:0> Task.first.closed_at
=> Fri, 07 Aug 2015 10:47:58 CEST +02:00

irb(main):012:0> Task.first.updated_at
=> Fri, 07 Aug 2015 10:47:58 CEST +02:00

irb(main):013:0> Task.first.closed_at == Task.first.updated_at
=> false

irb(main):014:0> Task.first.closed_at.to_datetime == Task.first.updated_at.to_datetime
=> false

I've read this two posts:

comparing datetime and time produces a false result

DateTime comparison fails in Rails

But neither the data type is different nor the time zone.

Environment:

Upvotes: 3

Views: 706

Answers (3)

raoul_dev
raoul_dev

Reputation: 1461

Try this little experiment with any model that has a created_at and updated_at in the console:

user = User.new
user.created_at = 'Fri, 07 Aug 2015 10:47:58 CEST +02:00'.to_datetime
user.updated_at = 'Fri, 07 Aug 2015 10:47:58 CEST +02:00'.to_datetime
user.created_at == user.updated_at

The last statement above returns true. So there has to be a difference in the time not visible when the time is displayed.

Upvotes: 2

Miguel Cunha
Miguel Cunha

Reputation: 663

This can happen because ruby Time makes comparison with fractions of seconds. So the "print" may look equal, but there is some time difference between both dates.

Try to use to_f method to see the difference between @task.closed_at and @task.updated_at. Pretty sure is this issue.

To solve your problem, just ignore the milliseconds part of dates:

<% if @task.closed_at.to_i == @task.updated_at.to_i %>
    *Some stuff*
<% end %>

Upvotes: 2

Yury Lebedev
Yury Lebedev

Reputation: 4015

It happens because of the little difference (in milliseconds) between those 2 variables. There is one blog post regarding this issue:

http://railsware.com/blog/2014/04/01/time-comparison-in-ruby/

Basically, an easy fix would be to convert the time values to int:

<% if @task.closed_at.to_i == @task.updated_at.to_i %>
    *Some stuff*
<% end %>

Upvotes: 1

Related Questions