Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare Time in ruby

Tags:

time

ruby

I need to use a Time object as a int (TimeObject.to_i) Then i need to convert a int back to a Time, to compare against the original Time. Short Example

t1 = Time.now
t2 = Time.at(t1.to_i)
puts t1 == t2    # Says False
puts t1.eql?(t2) # Says False

Why this says its false ? When i print both Time objetcs shows the same thing D:

puts t1                 #shows : 2012-01-06 16:01:53 -0300
puts t2                 #shows : 2012-01-06 16:01:53 -0300
puts t1.to_a.to_s       #shows : [ 53, 1, 16, 6, 1, 2012, 5, 6, true, "CLST"]      
puts t2.to_a.to_s       #shows : [ 53, 1, 16, 6, 1, 2012, 5, 6, true, "CLST"]      

they are the same thing D: but when trying to compare with == or eql? says they are diferent (sorry for my bad english)

like image 737
Robinson Hernandez Avatar asked Jan 06 '12 19:01

Robinson Hernandez


1 Answers

Answer

t1 = Time.now
t2 = Time.at(t1.to_i)
t3 = Time.at(t1.to_i)
puts t1  # 2012-01-06 23:09:41 +0400
puts t2  # 2012-01-06 23:09:41 +0400
puts t3  # 2012-01-06 23:09:41 +0400

puts t1 == t2      # false
puts t1.equal?(t2) # false
puts t1.eql?(t2)   # false

puts t2.equal? t3  # false
puts t2.eql? t3    # true
puts t2 == t3      # true

Explanation:

eql?(other_time)

Return true if time and other_time are both Time objects with the same seconds and fractional seconds.

Link: Time#eql?

So, apparently, fractions of seconds get dropped when performing #to_i and then restored time is not exactly the same as original one. But if we restore two copies, they will be equal.

One may think, "Hey, let's use #to_f then!". But, surprisingly enough, results are the same! Maybe it's because of rounding errors or floating point comparison, not sure.

Alternate answer

Don't convert integer back to time for comparison. Convert original time to int instead!

t1 = Time.now
t2 = Time.at(t1.to_i)

puts t1  # 2012-01-06 23:44:06 +0400
puts t2  # 2012-01-06 23:44:06 +0400

t1int, t2int = t1.to_i, t2.to_i

puts t1int == t2int           # true
puts t1int.equal?(t2int.to_i) # true
puts t1int.eql?(t2int)        # true
like image 188
Sergio Tulentsev Avatar answered Oct 14 '22 02:10

Sergio Tulentsev