Correctly handling multiple time zones in ruby on rails

Dec 06, 2007

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.

Installing time zone support into your rails app

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

Now before we do anything, make sure that we are defaulting to UTC time inenvironment.rb:

ENV['TZ'] = 'UTC'

Migrating your models so they know about time zones

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


class Election  [:start_at, :end_at], 
  :default_timezone => "America/Los_Angeles",
  :time_format => "%I:%M %p on %A %d %B %Y" 

Storing and retrieving time zones in your rails app

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 outlining

how 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:

Hi, I'm Glenn! 👋 I'm currently Director of Product @ HashiCorp, and we're hiring! If you'd like to come and work with me and help make Terraform Cloud even more amazing we have multiple positions opening in Product ManagementDesign, and Engineering & Engineering Management across a range of levels (i.e., junior through to senior). Please send in an application ASAP so we can get in touch.