timezone_fu makes it really easy to deal with multiple timezones between Rails Models. The plugin-in assumes that there is a model attribute called timezone that can be used for conversion.
Install the plugin:
ruby script/plugin install http://www.thrivesmart.com/open_source/timezone_fu/
In the model there is one method to enable this plugin-in: has_timezone.
has_attachment(options = {})
This method takes the following hash options:
- :fields => [ ] # array of fields you would like converted to local time automatically.
- :time_format => A string formatted for strftime (used by the display methods)
- :default_timezone => What timezone you want to use for conversions (used if the model's timezone attribute is empty.)
The plugin creates the following methods for each field passed in the fields array:
- :field_name - accessor that returns the field value formatted in local time
- :field_name=(val) - set the field's value to a time (in local time)
- :utc_field_name - accessor that returns the field value formatted in UTC time.
In More Detail
Timezone_fu makes it really easy to deal with datetime fields in your models. It adds a method to your models has_timezone that takes a hash of options. The README for the plugin describes all of the options but below is an example:
class Event < ActiveRecord::Base
has_timezone :fields => [ :start_datetime, :end_datetime]
end
Our Event model has three fields a start_datetime and end_datetime and a timezone. Adding has_timezone to the model changes the behavior of the two datetime attributes.
Notice below that calling event.start_datetime shows the time in local time ("America/New York").
>> event = Event.find(:first)
=> #<Event:0x1b71b40 @attributes={
"end_datetime" => "2007-11-21 15:00:00",
"start_datetime" => "2007-11-21 14:15:00",
"timezone" => "America/New_York"}
>> event.start_datetime
=> Wed Nov 21 09:15:00 UTC 2007
>> event.display_start_datetime
=> "Nov. 21, 2007 09:15 AM"
>> event.utc_start_datetime
=> Wed Nov 21 14:15:00 UTC 2007
You can also set the value of the field to a local date/time and it will be converted to UTC automatically:
>> event.start_datetime = Time.now
=> Sun Nov 25 06:26:35 +0000 2007
=> #<Biz::Event:0x1b71b40 @attributes={
"end_datetime" => "2007-11-21 15:00:00"
"start_datetime" => Sun Nov 25 11:26:35 +0000 2007,
"timezone" => "America/New_York" }
If you want to access the fields and retrieve the database value you can use the utc_field_name method to access the UTC value of the attribute. The plugin makes a couple of core assumptions. One it assumes that the default rails timezone is UTC:
ENV['TZ'] = 'UTC'
Second it assumes that the model has a timezone attribute named timezone:
t.column :timezone, :string, :default => ''
The plug-in depends on TZInfo and has been tested under Rails 1.2.3
You can grab a copy of the plug-in here: http://www.thrivesmart.com/open_source/timezone_fu.
Or if zipped is more your style: http://www.thrivesmart.com/open_source/timezone_fu.zip