如何在不同时区显示Rails表单日期时间选择?

我想在其首选时区向用户提供日期时间选择,但将日期时间存储为UTC。 目前,默认行为是使用UTC显示和存储日期时间字段。 如何在不影响整个应用程序的情况下更改此字段的行为(即不更改应用程序默认时区)?

更新:这不是每用户时区。 我不需要调整时间显示方式。 只有这些特定字段处理不同的时区,所以我希望用户能够指定此时区的时间。

以下是允许用户使用特定时区设置日期的方法:

要将表单中提交的多参数属性转换为特定时区,请在控制器中添加一个方法,以手动将参数转换为日期时间对象。 我选择将其添加到控制器,因为我不想影响模型行为。 您仍然可以在模型上设置日期并假设您的日期设置正确。

 def create convert_datetimes_to_pdt("start_date") convert_datetimes_to_pdt("end_date") @model = MyModel.new(params[:my_model]) # ... end def update convert_datetimes_to_pdt("start_date") convert_datetimes_to_pdt("end_date") # ... end def convert_datetimes_to_pdt(field) datetime = (1..5).collect {|num| params['my_model'].delete "#{field}(#{num}i)" } if datetime[0] and datetime[1] and datetime[2] # only if a date has been set params['my_model'][field] = Time.find_zone!("Pacific Time (US & Canada)").local(*datetime.map(&:to_i)) end end 

现在,日期时间将调整到正确的时区。 但是,当用户编辑时间时,表单字段仍将以UTC显示时间。 要解决这个问题,我们可以在调用Time.use_zone包装字段:

 Time.use_zone("Pacific Time (US & Canada)") do f.datetime_select :start_date end 

有几种选择:

  • 在向他们显示数据时利用用户的本地时区。 这很像浏览器timezone-rails gem。 请参阅https://github.com/kbaum/browser-timezone-rails 。 它基本上根据从浏览器检测到的时区覆盖每个请求的应用程序时区。 注意:它仅使用操作系统时区,因此它不如基于IP /地理位置的解决方案准确。
  • 设置应用程序时区,使其与大多数用户群保持一致。 例如: config.time_zone = 'Mountain Time (US & Canada)' 。 这是rails中非常标准的事情。 Rails将始终将数据存储在数据库中作为UTC,但将使用应用程序时区来呈现/加载它。
  • 为您的用户模型创建时区。 允许用户在其帐户设置中设置此值。 然后,在application_controller中使用与上述gem类似的方法。