Migrate to the Rails Default Time Zones
June 3rd, 2008 by TrevorI was recently upgrading my open-source app, El Dorado, up to Rails 2.1 and decided to switch over to the default time zones provided by the Rails. I'm not sure where I picked up the time zone definitions I was using before, but they were things like "US/Central" as opposed to "Central Time (US & Canada)".
Switching to the new time zone definitions provided by Rails means not having to rely on the TZInfo gem, because a stripped-down version is now packaged with Rails 2.1.
Here's the migration used to achieve this, which was made with some help from Geoff Buesing himself:
# db/migrate/20080603023415_use_rails_new_default_time_zones.rb class UseRailsNewDefaultTimeZones < ActiveRecord::Migration def self.up @users = User.all @users.each do |user| user.time_zone = 'UTC' if user.time_zone.blank? tz = TZInfo::Timezone.get(user.time_zone) rescue TimeZone[user.time_zone] || TimeZone['UTC'] time_zone = if tz.is_a?(TZInfo::Timezone) linked_timezone = tz.instance_variable_get('@linked_timezone') name = linked_timezone ? linked_timezone.name : tz.name TimeZone::MAPPING.index(name) else tz.name end user.update_attribute(:time_zone, time_zone) unless time_zone == user.time_zone end unless @users.empty? end def self.down end end
If you haven't played with the new time zone stuff in Rails 2.1, make sure to check it out. It makes dealing with time zones so easy, it's almost unbelievable. Thanks, Geoff!

I wrote a migration to set the user’s time zone by US state if you have a predominantly American user base.
You could change it’s default to UTC. It doesn’t have to do an update for every user record.
“You can find it here.”http://www.jrmiii.com/2008/6/3/quick-migration-to-set-user-time-zones-for-rails-2-1
Cheers
First, thanks for this script. I was a bit surprised that there is a lot of cheering about the new Rails time zone support, but I bet there are a lot of projects using the old TZInfo stuff and how to convert your time zones then? When I used the above script, I found a lot of zones are missing in the new system.
One of the things that I found is that the original TZInfo GEM has more zones, so the TZInfo::Timezone.get call retrieves more zones (e.g. Europe/Oslo). I kept this GEM before I converted my data and after that I removed it (of course I want as little external stuff as needed).
But I also added something to select at least the same time zone (with a different city) in case the old time zone can’t be found in TimeZone::MAPPING.
My migration looks like this (maybe it helps others), based on the example above. By the way, I kept the old time zone in a backup field, to make a backwards conversion possible (for the time being, that is).
def self.up
# convert all user time zones
change_column :users, :timezone, :string, :limit => 40, :null => false, :default => ‘London’
add_column :users, :old_timezone, :string, :limit => 40, :null => false, :default => ‘Europe/London’
execute ‘UPDATE users SET old_timezone = timezone’
User.all.each do |user|
tz = TZInfo::Timezone.get(user.timezone) rescue TimeZone[user.timezone] || TimeZone['UTC']
if tz.is_a?(TZInfo::Timezone)
linked_timezone = tz.instance_variable_get(’@linked_timezone’)
name = linked_timezone ? linked_timezone.name : tz.name
time_zone = TimeZone::MAPPING.index(name)
if time_zone.nil?
compatible_zones = TimeZone.all.select { |t| t.utc_offset == tz.current_period.offset.utc_total_offset }
time_zone = compatible_zones.empty? ? ‘UTC’ : compatible_zones.first.name
end
else
time_zone = tz.name
end
user.update_attribute :timezone, time_zone
end
def self.down
execute ‘UPDATE users SET timezone = old_timezone’
remove_column :users, :old_timezone
change_column :users, :timezone, :string, :limit => 40, :null => false, :default => ‘Europe/London’
end
(My field in the users table is called timezone).
[...] over time, various tips have cropped up to convert old to new. But neither tip worked good for me; I found them too [...]