Topic: Dailight Saving Time Bug

It appears that Daylight Savings doesn't work properly in the Rails Framework (SEE: http://dev.rubyonrails.org/ticket/2353)

My specific needs are for the tomorrow and yesterday methods.


Example of the problem:
Open up script/console and run the following commands.

t = Time.parse('2006-10-29')
#=> Sun Oct 29 00:00:00 -0400 2006

t.tomorrow
=> Sun Oct 29 23:00:00 -0500 2006

10-9-2006 happens to be a day where an hour is gained. The Rails framework goes forward exactly 24 hours, so 24 hours on a 25 hour day puts you on the same day.

I have developed a mixin that seems to fix this issue:

class Time

alias yesterday_orig yesterday
 
  ##############################################################################
  # Compensates for a Daylight Saving bug that could give inaccurate results.
  ##############################################################################
  def yesterday
    t = yesterday_orig
    return t if dst? == t.dst?
    if dst?
      t.since(1.hour)
    else
      t.ago(1.hour)
    end
  end
 
  alias tomorrow_orig tomorrow
 
  ##############################################################################
  # Compensates for a Daylight Saving bug that could give inaccurate results.
  ##############################################################################
  def tomorrow
    t = tomorrow_orig
    return t if dst? == t.dst?
    if dst?
      t.since(1.hour)
    else
      t.ago(1.hour)
    end
  end


end


This code works, but what I want to know if there is a better way to do this? Any thoughts would be appreciated.

Re: Dailight Saving Time Bug

I would create a days_since method and use that for everything (this is similar to how next_month/last_month is handled). Basically something like this:

def days_since(day_count)
  result = self.since(day_count.days)
  if dst? == result.dst?
    result
  elsif dst?
    result.since(1.hour)
  else
    result.ago(1.hour)
  end
end

def days_ago(days)
  days_since(-days)
end

def yesterday
  days_ago(1)
end

def tomorrow
  days_since(1)
end


Does that work?

Railscasts - Free Ruby on Rails Screencasts

Re: Dailight Saving Time Bug

I am not as interested in the method packaging as I am the logic itself. The logic I came up with appears to work, what I am wondering is if there is a better / more efficient way of solving the problem?

Re: Dailight Saving Time Bug

I know TZInfo offers better support for daylight savings time, but I think it is more for working with time zones, and I don't think this will solve the yesterday/tomorrow problem. Overriding the methods is the only way I know of to fix this.

Last edited by ryanb (2006-11-06 12:48:13)

Railscasts - Free Ruby on Rails Screencasts

Re: Dailight Saving Time Bug

Yeah I already played with the TZinfo library and it didn't solve this particular issue.

Re: Dailight Saving Time Bug

This was bugging me for a while too, but have a look at...

>> t = Time.parse('2006-10-29')
=> Sun Oct 29 00:00:00 EDT 2006
>> t.tomorrow
=> Sun Oct 29 23:00:00 EST 2006
>> t.advance(:days => 1)
=> Mon Oct 30 00:00:00 EST 2006

So now:

Class Time
  def tomorrow
    advance(:days => 1)
  end

  def yesterday
    advance(:days => -1)
  end
end


Ahhh. Now that is more like it.

Re: Dailight Saving Time Bug

I will give you one better. This issue is fixed in Rails v. 1.2.1!!