Ruby on Rails: Zeitzonen

Aus Wikibooks

Neu in Rails 2.1 ist die Unterstützung von Zeitzonen. Der Befehl "rake -T time" zeigt uns die neuen Rake-Tasks.

>rake -T time
rake time:zones:all    # Displays names of all time zones recognized by the...
rake time:zones:local  # Displays names of time zones recognized by the Rai...
rake time:zones:us     # Displays names of US time zones recognized by the ...

Eine ausführliche Beschreibung der Tasks liefert: "rake -D time".

Unsere Zeitzone finden wir mit "rake time:zones:local".

>rake time:zones:local
* UTC +01:00 *
Amsterdam
Belgrade
Berlin
Bern
..

Und die sollten wir gleich in "config/environment.rb" als Default einstellen.

Rails::Initializer.run do |config|
  ..  
  # Make Time.zone default to the specified zone, and make Active Record store time values
  # in the database in UTC, and return them converted to the specified local zone.
  # Run "rake -D time" for a list of tasks for finding time zone names. Uncomment to use default local time.
  config.time_zone = 'Berlin'
  ..
end

Danach werden alle Zeitangaben vor dem Speichern in universal Time (UTC) umgerechnet und beim Auslesen in die konfigurierte Zeitzone zurückübersetzt. Wir können das verifizieren, indem wir ein Zeitfeld mit "zeitfeld_before_type_cast()" ansehen. D.h., wenn wir eine Reise machen und in eine andere Zeitzone kommen, können wir das nur Rails sagen und schon gibt Rails alle Zeiten korrekt für die neue Zone aus.

Da wir die Zeitzone auch im Betrieb mit "Time.zone = .." umstellen können, können wir unseren Benutzern den selben Service bieten. Dazu fragen wir die Zeitzone ab ..

# views/users/new.html.erb
<%= f.time_zone_select :time_zone, TimeZone.all %>

.. und können dann mit einem before-Filter alle Zeiten Zonengerecht angezeigen.

# controllers/application.rb
before_filter :set_time_zone
 
def set_time_zone
  Time.zone = @current_user.time_zone if @current_user
end

Wenn wir uns die Zeitzone merken wollen, speichern wir sie in der Datenbank als String.

# ..add_time_zone_to_users.rb
Class AddTimeZoneToUsers << ActiveRecord::Migration
  def self.up
    add_column :users, :time_zone, :string
  end

  def self.down
    remove_column :users, :time_zone
  end
end