Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Time#since DST issue

#504

Here is some interesting result with Rails 2.1 (without any specific TimeZone configuration).

LONG STORY SHORT:

Loading development environment (Rails 2.1.0)
>> t = Time.parse("Sun Oct 26 00:30:00 +0200 2008")
=> Sun Oct 26 00:30:00 +0200 2008
>> (t+24.hours)==((t+3.hours)+21.hours)
=> false

DETAILS:

As you will see, adding 3.hours and then 21.hours doesn't give the same result as adding 24.hours around DST change!

I live in Europe, and DST change just happens at 02:00:00 in my TimeZone (which is most of Europe's). As expected:

>> t = Time.parse("Sun Oct 26 00:30:00 +0200 2008")
=> Sun Oct 26 00:30:00 +0200 2008
>> t2 = t+3.hours
=> Sun Oct 26 02:30:00 +0100 2008

As you can see, the "missing" hour is taken into account, which is what you would expect!

Now, let's add 21 more hours:

>> t2 = t2+21.hours
=> Sun Oct 26 23:30:00 +0100 2008

Which is right, too, since 24.hours have actually passed between the two displayed times!

However, now just try the following:

>> t
=> Sun Oct 26 00:30:00 +0200 2008
>> t3 = t+24.hours
=> Mon Oct 27 00:30:00 +0100 2008

Huho! There is something wrong here!

Is there anything I am missing?

I understand that in some situations, you might want to add "mathematical" hours (which means without taking care of DST or anything specific: 01:00 + 03:00 = 04:00 and that's it). And sometimes, you just want to add "real" hours, which means "what time is it when 3 hours have passed in the real life". Both are equally acceptable approaches. However, some kind of mix between the two is clearly a dangerous solution!

Reported by Nauhaie · June 28th, 2008 @ 10:26 AM

State: wontfix
Milestone: 2.x
Assigned to: Geoff Buesing Geoff Buesing
Importance: none

Activity

  1. Geoff Buesing
    Geoff Buesing
    • Title changed from Rails 2.1 DST Issues to Time#since DST issue
    • State changed from new to open
    • Tag changed from 2.1, bug, timezones to bug, dst, time
    • Assigned user set to Geoff Buesing

    I think this is because Time#since does a DST adjustment if the passed-in value is >= 86400 seconds -- hence, the difference between adding 24.hours and adding 3.hours + 21.hours.

    I think this behavior is a vestige from before Rails had the Duration class, so that you could do time.since(1.day) and have it adjust for DST changes. W should probably revisit this.

    If someone could write up a failing test case for this, that would be helpful.

    June 30th, 2008 @ 12:51 AM

  2. Nauhaie
    Nauhaie

    Hi Geoff,

    Thank's for your commit! But I still have the same problem :-(

    Loading development environment (Rails 2.0.991)

    >> t = Time.parse("Sun Oct 26 00:30:00 +0200 2008")

    => Sun Oct 26 00:30:00 +0200 2008

    >> (t+24.hours)==((t+3.hours)+21.hours)

    => false

    I think 24.hours, 21.hours and 3.hours are fixed-length time intervals, right?

    Here is how I got it:

    rails test_edge && cd test_edge

    rake rails:freeze:edge

    Then, I replaced the time_with_zone.rb in my vendor dir with your modified version

    ./script/console

    I did not set up anything else, and the problem is still the same...

    How is it possible?

    Thank you,

    Nauhaie

    July 10th, 2008 @ 08:32 AM

  3. Geoff Buesing
    Geoff Buesing

    Hi Nahuaie,

    I committed a similar fix to the TimeWithZone class, but the issue with the plain old Ruby Time class identified in this ticket is still outstanding.

    If you want to use the TimeWithZone class, you'll need to turn on config.time_zone for your app. See this tutorial for more.

    Geoff

    July 11th, 2008 @ 03:36 PM

  4. josh
    josh
    • State changed from open to wontfix

    October 28th, 2008 @ 04:25 PM

  5. Nauhaie
    Nauhaie

    I am sorry, but why "wontfix"?

    October 28th, 2008 @ 04:48 PM

  6. bingbing