Re: Duration

Matt Jones
Wed, 22 Dec 2010 21:35:29 -0000

On Dec 22, 12:09 pm, Marnen Laibow-Koser
<li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org>
wrote:
> Frederick Cheung wrote in post #970028:
>
> > On Dec 22, 6:41am, Jack Waugh
<7aq3z2h...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >> So far, so good.
>
> >> >> (y - x) / 1.second
>
> >> => Rational(28799745541, 28800000000)

There''s one gotcha here: the ''+ 1.day'' part appears
to drop the
microseconds part of the DateTime. For instance, this will show the
same sort of behavior:

>> d = DateTime.now
>> (d - Time.parse(d.inspect).to_datetime)*86400 # => a number smaller
than one; actually the undisplayed fractional seconds

Here the Time.parse chunk basically zeroes out everything but the
displayed parts of d, causing the difference. If I repeat your test
with this change:

>> x = DateTime.now
=> Wed, 22 Dec 2010 16:11:47 -0500

>> x_flat = Time.parse(x.inspect).to_datetime
=> Wed, 22 Dec 2010 16:11:47 -0500

>> y = x_flat + 1.day
=> Thu, 23 Dec 2010 16:11:47 -0500

>> y - x_flat
=> Rational(1, 1)

Which matches the definition of DateTime#-, returning a result in
days.

As to the division issue, I don''t think that''s the intended
reading
of .days and friends. It *used* to be (back when 1.day => 86400), but
that hasn''t been the behavior since 2007 in:

https://github.com/rails/rails/blob/276c9f29cde80fafa23814b0039f67504255e0fd/activesupport/lib/active_support/duration.rb

(would link to the old Trac ticket, but dev.rubyonrails.org seems to
be down). The ActiveSupport::Duration class was explicitly designed to
make + and - work correctly (corresponding to passing the given number
and unit to DateTime#adjust), not to do any other unit-related
conversions. If you want the old behavior, you can call .to_i on a
Duration:

>> 1.day.to_i
# => 86400

--Matt Jones