How to configure timezones in Ruby on Rails
When deploying an application to anynines the default time zone is “UTC +00:00”. However, when dealing with time in an application you usually don’t want to depend on the server time zone. This means the timestamps displayed in the views should be presented in the same timezone your users are in.
One timezone to rule them all
A first approach is to specify a default time zone for the whole application. A drawback of this method is that all of the application’s users will see the displayed times in the same timezone. For a Ruby on Rails application this is the method with the lowest effort.
1) List all timezones:
$ be rake time:zones:all
2) Configure a timezone you have chosen in step 1 (in config/application.rb)
config.time_zone = 'Berlin'
3) Display the timestamp in your views
<%= I18n.l(post.created_at) %>
Dealing with timezones
This first approach is sufficient when all your users are located in the same time zone. For many applications however this is not the case. To display timestamps in a user's own timezone you can use the following method:
For a user located in Germany:
<%= I18n.l(Time.now.in_time_zone('Berlin')) %>
This methods requires to store the user’s time zone in a database. For a Ruby on Rails application this means your user model has to be extended by a timezone attribute.
You can find more detailed information by reading this article from reinteractive on how to deal with timezones effectively in Rails.
Too long - didn’t read? Each time you need to show a date / time to a user, you should convert that time to the user's timezone. For example:
Time.now.in_time_zone(user.timezone).strftime(.... I18n.l(Time.now.in_time_zone(user.timezone).beginning_of_day)
The same is true for queries that should be relative to the user's timezone. Another strategy is to always convert the timezone in each request to the user's timezone with an around filter in your application controller:
class ApplicationController < ActionController::Base around_filter :set_time_zone def set_time_zone(&block) time_zone = current_user.try(:time_zone) || 'UTC' Time.use_zone(time_zone, &block) end end
If your are building a site that needs to show times and you don't have logged in users, you either use JavaScript on the front end to figure out the correct time to display, based on the user's browser, use the Detect Time Zone gem or use the user's IP address to infer the timezone.
Please sign in to leave a comment.
Comments
0 comments