home

TimeZones (with DST) in Rails

I was having a doozy of a time implementing TimeZone aware-ness in an application I’m buidling in Rails, until I found some excellent posts (see the bottom for spoiler). Here’s how I did it.

First, let’s make sure you’re storing every date in ActiveRecord in UTC.

You can either set your machine default to be UTC ( in gentoo linux that’s copying over a file from /usr/share/zoneinfo, in OS X, in the System Preferences), or you can setup your default rails environment to use UTC:

in environment.rb:

ActiveRecord::Base.default_timezone = :utc

Now, go and get the TZinfo gem, it’s a fix to the TimeZone support included in Ruby to make it Daylight Savings aware.

you could do:

$ sudo gem install TZInfo

Now add one more line to environment.rb:

require_gem ‘tzinfo’

Now, let’s say you’ve got a user with a time_zone — this could be as simple as (db migration magic here): add_column :users, :time_zone, :string ) of ‘America/Detroit’.

Add to the User Model:

class User < ActiveRecord::Base
  # …
  composed_of :tz, :class_name => ‘TZInfo::Timezone’,
                :mapping => %w(time_zone time_zone)
end

You can now say (script/console magic here) assuming your something object has the magic created_at datetime field:

something = Something.create
=> # < something :0×22db8d0 @errors=#<activerecord ::Errors:0×22d52a0 @errors={}, @base=# <Something:0×22db8d0 …> >, @attributes={"updated_at"=>Tue Mar 14 15:58:33 UTC 2006, "something"=>"", "created_at"=>Tue Mar 14 15:58:33 UTC 2006}, @new_record_before_save=true, @new_record=false>
user.tz.utc_to_local(something.created_at)
=> Tue Mar 14 10:58:33 UTC 2006

Not there’s still a “UTC” stamp on that bad boy, but now you’ll never show that long format since you’ve got it stored with their Time zone.

Update: You can do:

< %= time_zone_select ‘user’, ‘time_zone’, TZInfo::Timezone.us_zones.sort, :model => TZInfo::Timezone % >

which sorts the us_zones, but hmmm, as for the rest of ‘em, good luck. ;-) How very American, eh?

See Using TZInfo in Rails and the TZInfo - Ruby Timezone Library for more info.

4 Responses to “TimeZones (with DST) in Rails”

  1. Derek
    March 14th, 2006 16:24
    1

    Very cool…need to add this to 2 different apps!

  2. Greg
    March 17th, 2006 14:42
    2

    Thanks, this is very helpful!

  3. Alex
    April 15th, 2006 08:34
    3

    Is there any easy way to format the TZInfo output so it looks like the built in list in Rails’ time_zone_select helper?

  4. seebq
    April 15th, 2006 08:54
    4

    There really is no way, since now you’re asking for TimeZones in a different “format” — no longer are you asking if they are -5:00 EST Hours from GMT (or -6:00 Hours ESTEDT during daylight savings), but rather, what is the real time-zone that you abide by….

    The drop-down, I’ll admit is a little nasty. It has quite a few U.S. zones that I’ve never heard of. I could be wrong, though.

Leave a Reply

Type the word "seebq" here: