Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Time object converted from float doesn't equal to orignial Time object

time = Time.now
fvalue = time.to_f
return time == Time.at(fvalue)

Can somebody here explain why the above expression returns false. How can I create a new Time object from float that matches the original time variable?

Thanks

like image 831
user1086039 Avatar asked Sep 09 '13 21:09

user1086039


1 Answers

IEEE 754 double (which is returned by to_f) is not accurate enough to represent the exact time.

t1 = Time.now
f1 = t1.to_f
t2 = Time.at(f1)

# they look the same
t1.inspect #=> '2013-09-09 23:46:08 +0200'
t2.inspect #=> '2013-09-09 23:46:08 +0200'

# but double does not have enough precision to be accurate to the nanosecond
t1.nsec #=> 827938306
t2.nsec #=> 827938318
#                  ^^

# so they are different
t1 == t2 #=> false

Do the following, to preserve the exact time:

t1 = Time.now
r1 = t1.to_r # value of time as a rational number
t2 = Time.at(r1)
t1 == t2 #=> true

Citation from Time.to_r:

This methods is intended to be used to get an accurate value representing the nanoseconds since the Epoch. You can use this method to convert time to another Epoch.

like image 80
tessi Avatar answered Sep 28 '22 09:09

tessi