Reputation: 4164
So I was having a problem with finding records by using one of the object property which is of class Time
.
Turns out that when I pass in the time as a params
to my controller, which in turn sends it to the model... the time
object I'm sending gets stringified.
So I thought I will just convert it back to Time either by Time.parse(<stringified time>)
or <stringified time>.to_time
- (Using rails)
But my test keeps failing, so I decided to do some look into what was going on there.
This was what I found out:
2.2.0 :003 > a = Time.now
=> 2015-10-14 20:50:19 +0100
2.2.0 :004 > b = a.to_s
=> "2015-10-14 20:50:19 +0100"
2.2.0 :005 > c = Time.parse b
=> 2015-10-14 20:50:19 +0100
2.2.0 :006 > c == a
=> false
2.2.0 :007 > a.class
=> Time
2.2.0 :008 > c.class
=> Time
2.2.0 :015 > a - c
=> 0.951439
2.2.0 :016 > d = b.to_time
=> 2015-10-14 20:50:19 +0100
2.2.0 :017 > c - d
=> 0.0
My confusion is mostly from the line: a - c
which gave me 0.951439
. Where did this difference come from?
Most importantly, how do I make these two to be equal? Thanks much, all.
Upvotes: 2
Views: 117
Reputation: 10951
The reason:
Since Ruby 1.9.2, Time implementation uses a signed 63 bit integer, Bignum or Rational. The integer is a number of nanoseconds since the Epoch which can represent 1823-11-12 to 2116-02-20. When Bignum or Rational is used (before 1823, after 2116, under nanosecond), Time works slower as when integer is used.
And if you run a = Time.now
you got N seconds since the Epoch plus P nanoseconds. But when you run Time.parse b
you got same number seconds but with zero nanosecond. This is what you're looking for.
Loading development environment (Rails 4.2.4)
[1] pry(main)> a = Time.now
=> 2015-10-14 23:41:12 +0300
[2] pry(main)> a.nsec
=> 733355000
[3] pry(main)> Time.parse(a.to_s).nsec
=> 0
So you have to avoid this nano stuff. For instance you can write something like that:
[16] pry(main)> a = Time.at(Time.now.to_i)
=> 2015-10-14 23:47:59 +0300
[17] pry(main)> a.nsec
=> 0
Upvotes: 2