Reputation: 30232
Test setup
irb(main):001:0> require 'date'
=> true
irb(main):007:0> require 'active_support/all'
=> true
irb(main):002:0> start = Date.new(2016,10,1)
=> #<Date: 2016-10-01 ((2457663j,0s,0n),+0s,2299161j)>
irb(main):003:0> finish = Date.new(2016,11,1)
=> #<Date: 2016-11-01 ((2457694j,0s,0n),+0s,2299161j)>
I expect that both finish-start.div
to return 1 (or 0) but mostly be consistent. Yet oddly when I do use Date objects it returns 0 but when I take the same Date object and convert it to_time it returns 1.
irb(main):008:0> (finish-start).div(1.month)
=> 0
irb(main):009:0> start + 1.month <= finish
=> true
irb(main):010:0> (finish.to_time - start.to_time).div(1.month)
=> 1
irb(main):011:0> start.to_time + 1.month <= finish.to_time
=> true
Why is that? What is going on?
Upvotes: 0
Views: 37
Reputation: 4440
When you calculate
finish-start
#=> (61/1) #(days/hours+1)
and
finish.to_time - s.to_time
#=> 2592000 #seconds
for check result of div
you can use divmod
(finish-start).divmod(1.month)
=> [0, (31/1)]
(finish.to_time - start.to_time).divmod(1.month)
=> [1, 90000.0]
to make it work the same, you can use the next:
(finish-start).days.to_i.divmod(1.month.to_i)
#=> [1, 86400]
Upvotes: 0
Reputation: 114268
finish - start
invokes Date#-
and returns the number of days, i.e. 31:
finish - start
#=> (31/1)
finish.to_time - start.to_time
on the other hand invokes Time#-
and returns the number of seconds, i.e. 60 × 60 × 24 × 31:
finish.to_time - start.to_time
#=> 2682000.0
1.month
returns a ActiveSupport::Duration
instance equivalent to the number of seconds in a 30-day month i.e. 60 × 60 × 24 × 30:
1.month.to_i
#=> 2592000
1.month == 2592000
#=> true
With the above in mind, your calculations are equivalent to:
31 / 2592000 #=> 0
2682000 / 2592000 #=> 1
Upvotes: 1