DonMB
DonMB

Reputation: 2718

Rails time_zone_select to use "official" time zone values

My view (haml):

= f.time_zone_select :time_zone, nil, {}, class: 'form-control'

Renders to:

...
<option value="Ljubljana">(GMT+01:00) Ljubljana</option>
<option value="Madrid">(GMT+01:00) Madrid</option>
<option value="Paris">(GMT+01:00) Paris</option>
<option value="Prague">(GMT+01:00) Prague</option>
...

When creating a record I want to set the :time_zone attribute to the current time zone of the user. There are several ways to do this but after researching I found either the gem timezone_local or the JS library jstz most common ones. Either way, all those open source libraries seem to use a different pattern then rails does, e.g the Paris timezone is defined as:

Europe/Paris

However, the TimeZone object in Rails uses

Paris

this leads to inconsistencies when I want to create a record with the current time zone of the user as it won't match. I need rails to use the same patterns as jstz or vice versa but I don't want to gsub strings here or similiar. What is the best approach here?

Upvotes: 7

Views: 1779

Answers (2)

Jonathan Lin
Jonathan Lin

Reputation: 20694

Use .select instead of .time_zone_select:

<%= f.select :timezone, ActiveSupport::TimeZone.all.collect {|tz| ["(GMT#{ActiveSupport::TimeZone.seconds_to_utc_offset(tz.utc_offset)}) #{tz.name}", tz.tzinfo.name]}, { include_blank: true } %>

Upvotes: 3

Jerph
Jerph

Reputation: 4570

You can use Draper to modify all and name (the list and value methods used by time_zone_select):

class TimeZoneDecorator < Draper::Decorator
  decorates ActiveSupport::TimeZone
  delegate_all

  def self.all
    TimeZoneDecorator.decorate_collection(ActiveSupport::TimeZone.all)
  end

  def self.us_zones
    TimeZoneDecorator.decorate_collection(ActiveSupport::TimeZone.us_zones)
  end

  # other custom collection methods

  def name
    tzinfo.name # "Europe/Paris" instead of "Paris"
  end
end

And then use the model option in your tag:

= f.time_zone_select :timezone, TimeZoneDecorator.us_zones, {include_blank: "Set from Lat/Lng", model: TimeZoneDecorator}, {class: 'form-control'}

Upvotes: 2

Related Questions