What time is it? Or, handling timezones in Rails.

Posted Posted by Wes in Programming, Ruby on Rails     Comments 6 comments
Oct
22

As a followup to a stack overflow answer, I thought I would give some examples of working with time zones in rails.

What does Rails timezone support do for me?

  • Stores everything in UTC in the database
  • Allows you to set an application default timezone and/or timezones for your users
  • Automatically converts UTC in the database to the correct zone and back

What zones are available?

You can get a list of timezones with rake tasks:

# Displays names of all time zones recognized by the Rails TimeZone class, grouped by offset.
rake time:zones:all

# Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time
rake time:zones:local

# Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset.
rake time:zones:us

Setting the default time zone

In your environment.rb (Rails 2) or application.rb (Rails 3) file, you can set the default timezone:

config.time_zone = 'Central Time (US & Canada)'

What does this do? By setting an application-wide timezone, any datetime will be stored in UTC in the database, but will be translated when we access it.

Set a timezone for a user

You can use time_zone_select to get a list of timezones for a user to pick from. The third argument is a list of “priority” zones that will appear first.

 time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")

Once the value is saved in the database, you’ll want to set it for each request, per user:

  before_filter :set_timezone

  def set_timezone
    # current_user.time_zone #=> 'Central Time (US & Canada)'
    Time.zone = current_user.time_zone || 'Central Time (US & Canada)'
  end

[UPDATE: You'll need a field 'time_zone' in your user table!]

[UPDATE: You probably want to stay DRY and refer to the configured value instead of specifying the timezone value in both places:
Time.zone = current_user.time_zone || MyAppName::Application.config.time_zone]

Let me know if you have questions or improvements and I’ll integrate them into the article. Thanks!

6 Comments to “What time is it? Or, handling timezones in Rails.”

  • I put

    1. before_filter :set_timezone
    2.
    3. def set_timezone
    4. # current_user.time_zone #=> ‘Central Time (US & Canada)’
    5. Time.zone = current_user.time_zone || ‘Central Time (US & Canada)’
    6. end

    in my application_controller.rb but when I always get this error:

    undefined method ‘time_zone’ for #

    I would appreciate if anyone could help me with this.

  • Max,
    I hope you figured out your problem. Your problem is that your user object doesn’t have a time_zone attribute. You can create a migration to fix that, and then just store the user’s time zone.

    -Damien

  • You could also use “MyAppName::Application.config.time_zone” as the default. E.g.

    Time.zone = current_user.time_zone || MyAppName::Application.config.time_zone

    Then you would just have one single, unambiguous, authoritative representation of the default time zone (DRY).

    Thanks for the post. Clear and concise.

  • @George: I considered that, but you’d have different syntaxes for Rails 2 and Rails 3. Added a note about referring to that, though, as it’s definitely the right way to do it.

  • [...] What time is it? Or, handling timezones in Rails [...]

  • Awesome post, very helpful!

    A quick note for Rails 3 users — the time_zone_select helper now is part of ActiveSuport, so must be qualified, as in


    time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)")

Post comment

about databasically

We live and work in Kansas City, USA.

We're passionate about helping small businesses succeed and want to help you use technology to get more done.

From server, desktop, network management to programming custom web applications in Ruby on Rails, we're here to lend a hand.

Contact us if you have any questions!