A recent client I was working for had the unfortunate situation where we'd
both independently assumed we understood the requirements, without realising
a missing piece of complexity. It was around time zones. The system was
implemented with a cut-off date being US EST, but most of their clientele
are in LA so it needed to be US PST. What is a developer to do?
Well it turns out that timezone_fu will come to the rescue.
Getting timezone_fu working with an existing rails app is a cinch, the only
dependency is on the TZInfo package, so best you
grab that now:
sudo gem install tzinfo
And the install the plugin in your rails app:
./script/plugin install http://www.thrivesmart.com/open_source/timezone_fu
Now before we do anything, make sure that we are defaulting to UTC time inenvironment.rb:
ENV['TZ'] = 'UTC'
Next, take your model that you want to apply your dates to. In my scenario it
was an election which had a start and end date for when voting could occur. First
thing I needed to do was to add a field to record the time zone that the dates
were to be handled in:
class AddTimezoneToElections
And then amend my model definition in election.rb to add in the time zone
helper:
class Election [:start_at, :end_at],
:default_timezone => "America/Los_Angeles",
:time_format => "%I:%M %p on %A %d %B %Y"
end
The wonderful thing about this setup is that dates saved or retrieved from the
model using the normal attribute accessors will displayed in the local time (as
determined by whatever you save in the timezone field). I've also used all of
the attributes to show their usage, but you can safely leave efault_timezone and
ime_format off if you desire. The latter is a strftime string format outlininghow to format the string, so we can get something like:
>> @election.display_end_at
=> "08:10 PM on Wednesday 20 February 2008"
Unfortunately though the strftime method used by the display_attribute helpers
still thinks that the timezone is in UTC format (I'll hopefully get around to a
patch shortly), so within my views to display the date with the timezone it is
actually more like: