Posted by Kenny Johnston on 05/15/2010
Whenever you are developing an application that will have users located in more than one time zone you will run into a need for time zone translations. Time zones may not be your favorite topic, particularly if you’re going to be dealing with scheduling events across time zones by users who reside in other time zones. But fear not, Rails makes time zone handling quite easy, with just a little upfront configuration.
Since we need to know each user’s time zone, we’ll need a migration to store their time zone selection, so let’s generate one:
script/generate migration add_user_time_zone
The migration should look something like:
class AddUserTimeZone < ActiveRecord::Migration def self.up add_column :users, :time_zone, :string, :default => 'Pacific Time (US & Canada)' end def self.down remove_column :users, :time_zone end end
Here is a time zone select field, populated by ActiveSupport, with all of the supported time zones:
<%= time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones %>
The following addition to ApplicationController will ensure logged in users have their time zone applied at the beginning of each transaction (as soon as a request hits a controller). This assumes you have current_user and logged_in? methods like restful_authentication provides, adjust as necessary.
before_filter :set_time_zone protected def set_time_zone Time.zone = current_user.time_zone if logged_in? end
This concludes the setup process. Now that you have a mechanism in place for setting the user’s time zone at the beginning of each transaction, you can configure your methods that deal with dates and times to translate their output to that time zone. The following example could be used to return the created_at (UTC) date to something that looks like “May 16, 2010 4:20:00PM PDT.”
def sent_at Time.zone.parse(created_at.to_s).strftime("%B %e, %Y %l:%M:%S %Z") end
Note that the parse command is expecting a string. From here on out you’ll want to get used to using the “%Z” when you use the strftime method as you’ll want it to be clear to you as you’re developing and the user as they interact with the system what times have been translated and to which time zones.