I found recently this strange behaviour concerning instanciating a Time object (like for instance, using Time.now) and then using its value for arithmetic operations that in the end will return an Integer. My use case is the following:
I instantiate a Time:
time = 3.days.from_now
I then use it to know the number of seconds from now til that time:
now = Time.now
diff = time - now #=> returns an Integer
Now I store that time in the DB (lets assume a is an ActiveRecord-like instance which will store time in a DATETIME column):
a.date = time
a.save
Now it comes to the trickiest part:
a.reload
time2 = a.date
diff2 = time2 - now #=> returns an Integer
diff == diff2
The last assertion will sometimes be false, others be true. Thing is, When one instantiates the Time object, its value used for the Time arithmetic operations contains precision up to nanoseconds and microseconds, which will be taken into account in the resulting value of a “-” operation. But as it is stored, the “microprecision” is left behind, and when the time stored in the db is loaded, it comes with no nanoseconds or microseconds. Therefore, it is inherently different from the time instance I previously assigned to that object’s attribute. And that messes my difference calculations.
So, the question would be: How can I instantiate from Time so that the instance will precision only up to seconds and will therefore be equivalent to a time fetched from db if that time instance would be eventually stored? I would prefer an ActiveSupport-independent solution, even though AS-suggestions are also welcome. The goal is: diff must be equal to diff2 ALL the time.
If you only need to truncate a
Timeto a second, you can use this, for example:instead of
Time.nowEdit: Just noticed
Time#roundmethod:should do the trick as well.