Re: Duration

Frederick Cheung
Tue, 21 Dec 2010 20:24:20 -0000

On Dec 21, 5:17 pm, Jack Waugh
<7aq3z2h...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> It looks as though if you ask a DateTime to add something to itself,
> it looks at the something, and if it''s an integer, it interprets
it as
> a duration in seconds, but if it''s a Rational, it interprets it as
a
> duration in days.

That''s not actually the whole store - If you did DateTime.now + 1 then
you would get 1 day after now.
The key is that 1.second (and similarly 3.days, 2.hours + 6.minutes
etc) aren''t integers - they''re ActiveSupport::Duration
objects.
They quite often pretend to be integers (the number of seconds
represented by the duration - although this is obviously dodgy if the
duration is something like 1 month), largely because that''s quite
convenient when dealing with Time objects and I suspect because of
backwards compatibility (at one point in Rails'' history
the .second/.day... methods were just convenience methods that
returned the corresponding number of seconds)

>
> It''s inconsistent.  Why didn''t the designers settle on
one type for
> durations and one way to interpret them?  What should one store in a
> database for a duration?  What rules should one follow to avoid being
> tripped up by numbers being interpreted as different measures
> depending on accidental features such as the numbers''
> representations?  This is very disappointing; engineering designs
> should make logical sense.

It depends on what the duration represents. Sometimes you really do
just mean some fixed length of time, so storing a integer number of
seconds is good enough. It''s often more complicated though, for
example if a duration is 1 month then your users might expect the 3rd
october to be followed by 3rd november and then by the 3rd of december
even though those are actually different numbers of seconds. Similarly
users will often expect that things that are 1 day long will end/start
on the same time every day, even though when clocks go back/forward a
day in local time is actually 23/25 hours long.

Fred



>
> >> x = DateTime.now
>
> => Tue, 21 Dec 2010 12:10:14 -0500>> d1 = 1.second
> => 1 second
> >> y = x + d1
>
> => Tue, 21 Dec 2010 12:10:15 -0500>> y.class
> => DateTime
> >> y - x
>
> => Rational(1, 86400)>> d2 = y - x
>
> => Rational(1, 86400)>> d1.class
> => Fixnum
> >> d1
> => 1 second
> >> 0 + d1
> => 1
> >> d1 == d2
> => false
> >> (x + d1) == (x + d2)
>
> => true