time_zone_options_for_select将UTC时间点打印为值

时间:2014-08-08 09:05:07

标签: ruby-on-rails ruby

我有这段代码让用户选择他们的时区。

<%= time_zone_options_for_select(@corp.timezone, nil, ActiveSupport::TimeZone) %>

问题是代码产生了这个html

<option value="American Samoa">(GMT-11:00) American Samoa</option>

我需要它像下面的

<option value="-11:00">(GMT-11:00) American Samoa</option>

我如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

您需要存储偏移的任何特殊原因?我建议像这样简化:

保持视图相同

time_zone_options_for_select(@corp.timezone, nil, ActiveSupport::TimeZone)

模型

validates :timezone, inclusion: { in: ActiveSupport::TimeZone.zones_map.keys }

转换

DateTime.now.in_time_zone(@corp.timezone)

DateTime.now.in_time_zone("Hawaii")
# => Thu, 07 Aug 2014 23:19:03 HST -10:00

然而,要回答你的问题。请参阅time_zone_options_for_select的文档以及源代码。

最后一个参数采用模型。在这种情况下,ActiveSupport::TimeZone。然后使用model.all获取时区列表,并将标签,值(分别)提取为[instance.to_s, instance.name]

注意,每个TimeZone实例都有utc_offset

TimeZone.new("Hawaii").utc_offset
# => -36000

这意味着您可以传递time_zone_options_for_select您自己的实现self.all和补丁instance.name的自定义类。


您也可以跳过time_zone_options_for_select并使用options_for_select,传入此自定义数组:

辅助

def timezone_options
  ActiveSupport::TimeZone.all.map do |zone|
    [zone.to_s, timezone_to_offset_string(zone)]
  end
end

def timezone_to_offset_string(timezone)
  (timezone.utc_offset / 3600).to_s + ":00"
end

视图

options_for_select(timezone_options, @corp.timezone)

但是你失去priority的{​​{1}}选项。所以,正如你所看到的,最好只遵守惯例。