Howdy,
We internationalized our site months ago, but forgot one part: The drop down where a user picks their timezone.
How do you translate the following line:
= f.time_zone_select :timezone, ActiveSupport::TimeZone.all
Howdy,
We internationalized our site months ago, but forgot one part: The drop down where a user picks their timezone.
How do you translate the following line:
= f.time_zone_select :timezone, ActiveSupport::TimeZone.all
I would imagine that this would need to be done manually in the same way that any other I18n translations are done in Rails. This would mean setting up locale files with the translations. Something like:
# es.yml
es:
timezones:
"International Date Line West": "Línea de fecha internacional del oeste"
"Pacific Time (US & Canada)": "Tiempo pacífico (& de los E.E.U.U.; Canadá)"
# and so on
You could overwrite the time_zone_options_for_select
method (which is used by time_zone_select
) with the following:
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
zone_options = ""
zones = model.all
convert_zones = lambda do |list|
list.map do |z|
localized_name = I18n.t(z.name, :scope => :timezones, :default => z.name)
[ "(GMT#{z.formatted_offset}) #{localized_name}", z.name ]
end
end
if priority_zones
if priority_zones.is_a?(Regexp)
priority_zones = model.all.find_all {|z| z =~ priority_zones}
end
zone_options += options_for_select(convert_zones[priority_zones], selected)
zone_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
zones = zones.reject { |z| priority_zones.include?( z ) }
end
zone_options += options_for_select(convert_zones[zones], selected)
zone_options
end
The changes are:
convert_zones = lambda do |list|
list.map do |z|
localized_name = I18n.t(z.name, :scope => :timezones, :default => z.name)
[ "(GMT#{z.formatted_offset}) #{localized_name}", z.name ]
end
end
What we're doing is, getting the localized name from the TimeZone name with I18n.t which is looking in config/locales/LANG.yml
formatted as shown above. If we can't find the translation, we just fallback on using the TimeZone name.
Now that we've done this setup, we should be able to use :
f.time_zone_select :timezone, ActiveSupport::TimeZone.all
or the shorter
f.time_zone_select :timezone # defaults to ActiveSupport::TimeZone.all
I've come across the same problem. However, when I was trying to implement Peter's solution, a simpler solution occurred to me. The time_zone_select
helper takes a :model
option, which defaults to ActiveSupport::TimeZone
. According to the API documentation, all this model has to do is return an array of timezone objects in the all
method. We can then override the to_s
method to return the translation (defaulting to the original if the translation isn't found). Here is the class:
# lib/i18n_time_zone.rb
class I18nTimeZone < ActiveSupport::TimeZone
def self.all
super.map { |z| create(z.name, z.utc_offset) }
end
def to_s
translated_name = I18n.t(name, :scope => :timezones, :default => name)
"(GMT#{formatted_offset}) #{translated_name}"
end
end
And in the view:
<%= time_zone_select :user, :time_zone, nil, :model => I18nTimeZone %>
With the translations specified in the translation file as before:
# es.yml
es:
timezones:
"International Date Line West": "Línea de fecha internacional del oeste"
"Pacific Time (US & Canada)": "Tiempo pacífico (& de los E.E.U.U.; Canadá)"
# and so on
I had the same problem and fishwebby's answer made the trick easily. I needed the time zones translated to spanish so here I leave the list:
"International Date Line West": "Línea de fecha internacional del oeste"
"Midway Island": "Isla de Midway"
"Samoa": "Samoa"
"Hawaii": "Hawai"
"Alaska": "Alaska"
"Pacific Time (US & Canada)": "Hora del Pacífico (EE.UU. y Canadá)"
"Tijuana": "Tijuana"
"Mountain Time (US & Canada)": "Hora de las Montañas (EE.UU. y Canadá)"
"Arizona": "Arizona"
"Chihuahua": "Chihuahua"
"Mazatlan": "Mazatlán"
"Central Time (US & Canada)": "Hora central (EE.UU. y Canadá)"
"Saskatchewan": "Saskatchewan"
"Guadalajara": "Guadalajara"
"Mexico City": "Ciudad de México"
"Monterrey": "Monterrey"
"Central America": "América Central"
"Eastern Time (US & Canada)": "Hora del Este (EE.UU. y Canadá)"
"Indiana (East)": "Indiana (Este)"
"Bogota": "Bogotá"
"Lima": "Lima"
"Quito": "Quito"
"Atlantic Time (Canada)": "Hora del Atlántico (Canadá)"
"Caracas": "Caracas"
"La Paz": "La Paz"
"Santiago": "Santiago"
"Newfoundland": "Terranova"
"Brasilia": "Brasilia"
"Buenos Aires": "Buenos Aires"
"Georgetown": "Georgetown"
"Greenland": "Groenlandia"
"Mid-Atlantic": "Atlántico medio"
"Azores": "Azores"
"Cape Verde Is.": "Isla Cabo Verde"
"Dublin": "Dublín"
"Edinburgh": "Edimburgo"
"Lisbon": "Lisboa"
"London": "Londres"
"Casablanca": "Casablanca"
"Monrovia": "Monrovia"
"UTC": "UTC"
"Belgrade": "Belgrado"
"Bratislava": "Bratislava"
"Budapest": "Budapest"
"Ljubljana": "Ljubljana"
"Prague": "Praga"
"Sarajevo": "Sarajevo"
"Skopje": "Skopje"
"Warsaw": "Varsovia"
"Zagreb": "Zagreb"
"Brussels": "Bruselas"
"Copenhagen": "Copenhague"
"Madrid": "Madrid"
"Paris": "París"
"Amsterdam": "Amsterdam"
"Berlin": "Berlín"
"Bern": "Berna"
"Rome": "Roma"
"Stockholm": "Estocolmo"
"Vienna": "Viena"
"West Central Africa": "Centro-Oeste de África"
"Bucharest": "Bucarest"
"Cairo": "El Cairo"
"Helsinki": "Helsinki"
"Kyev": "Kyev"
"Riga": "Riga"
"Sofia": "Sofía"
"Tallinn": "Tallin"
"Vilnius": "Vilnius"
"Athens": "Atenas"
"Istanbul": "Estambul"
"Minsk": "Minsk"
"Jerusalem": "Jerusalén"
"Harare": "Harare"
"Pretoria": "Pretoria"
"Moscow": "Moscú"
"St. Petersburg": "San Petersburgo"
"Volgograd": "Volgogrado"
"Kuwait": "Kuwait"
"Riyadh": "Riad"
"Nairobi": "Nairobi"
"Baghdad": "Bagdad"
"Tehran": "Teherán"
"Abu Dhabi": "Abu Dhabi"
"Muscat": "Moscatel"
"Baku": "Bakú"
"Tbilisi": "Tbilisi"
"Yerevan": "Ereván"
"Kabul": "Kabul"
"Ekaterinburg": "Ekaterinburg"
"Islamabad": "Islamabad"
"Karachi": "Karachi"
"Tashkent": "Tashkent"
"Chennai": "Chennai"
"Kolkata": "Kolkata"
"Mumbai": "Mumbai"
"New Delhi": "Nueva Delhi"
"Kathmandu": "Katmandú"
"Astana": "Astana"
"Dhaka": "Dhaka"
"Sri Jayawardenepura": "Sri Jayawardenepura"
"Almaty": "Almaty"
"Novosibirsk": "Novosibirsk"
"Rangoon": "Rangún"
"Bangkok": "Bangkok"
"Hanoi": "Hanoi"
"Jakarta": "Yakarta"
"Krasnoyarsk": "Krasnoyarsk"
"Beijing": "Beijing"
"Chongqing": "Chongqing"
"Hong Kong": "Hong Kong"
"Urumqi": "Urumqi"
"Kuala Lumpur": "Kuala Lumpur"
"Singapore": "Singapur"
"Taipei": "Taipei"
"Perth": "Perth"
"Irkutsk": "Irkutsk"
"Ulaan Bataar": "Ulán Bator"
"Seoul": "Seúl"
"Osaka": "Osaka"
"Sapporo": "Sapporo"
"Tokyo": "Tokio"
"Yakutsk": "Yakutsk"
"Darwin": "Darwin"
"Adelaide": "Adelaida"
"Canberra": "Canberra"
"Melbourne": "Melbourne"
"Sydney": "Sydney"
"Brisbane": "Brisbane"
"Hobart": "Hobart"
"Vladivostok": "Vladivostok"
"Guam": "Guam"
"Port Moresby": "Port Moresby"
"Magadan": "Magadan"
"Solomon Is.": "Islas Salomón"
"New Caledonia": "Nueva Caledonia"
"Fiji": "Fiji"
"Kamchatka": "Kamchatka"
"Marshall Is.": "Islas Marshall"
"Auckland": "Auckland"
"Wellington": "Wellington"
"Nuku'alofa": "Nuku'alofa"
fishwebby's solution didn't work for me when priority time zones where provided in the time_zone_select. Easiest is to just stick this in /config/initializers/time_zone_patch.rb :
# See http://stackoverflow.com/questions/1396623/translating-rails-timezones
class ActiveSupport::TimeZone
def to_s
offset = "(GMT#{formatted_offset})"
translated_name = I18n.t(name, :scope => :time_zones, :default => name)
%(#{offset} #{translated_name})
end
end
No need to modify your view code either.