Rails:鉴于我的数据库是UTC,而我的Time.zone US Eastern,我如何在美国太平洋节省时间?

Dan*_*iel 4 ruby time timezone ruby-on-rails

(我在Ruby MRI 1.9.2上使用Rails 3.2.3)

一切都以UTC为中心存储.这很好.每个用户都有一个'时区'属性.我的ApplicationController有一个前置过滤器,可以将Time.zone调整为用户存储的时区.这也很好.

鉴于上述情况,如果我的用户用时间完成日期时间选择,那么该时间应该在Time.zone中,并且Rails将自动调整并将其保存为UTC.这也是好的.

现在:我希望我的用户能够在另一个时区填写一个时间,然后将其存储为UTC.但是,Rails期望已完成的日期时间选择(在之前由ApplicationController设置)Time.zone中填写.因此Rails会错误地调整为UTC .

如何实现我的目标,即将输入的时间保存为第三时区?

插图:

我的使用场景是佛罗里达州的用户调整属于西海岸酒店的文档的日期.他们希望进入西海岸的时间.

我正在使用jQuery来设置带有样式选择器的文本框,所以我有一个方法将字符串输出到文本框:

<%= f.text_field(:created_at, :value => adjusted_to_hotel_time(@document.created_at), :class => 'text datetime_picker') %>

def adjusted_to_hotel_time(time)
  time.in_time_zone(@current_hotel.timezone).to_s(:admin_jquery) # formatted for the jQuery datetime_picker text fields.
end
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是当保存@document时,Rails会错误地调整为UTC.我不知道我不知道的是什么 - 如何将在该字段中输入的数据"标记"为@ current_hotel.timezone,以便Rails在保存父对象时将正确地偏移到UTC?

Dan*_*iel 13

破了!

基本上,提交给params的字符串表示酒店时区的时间.我们必须使用内置的"use_zone"方法临时将全局Time.zone设置为该酒店.

然后,我们通过使用酒店的时区而不是用户,将方法传递给我们生成Rails期望值的块.这意味着Rails转换为UTC会导致数据库中的正确时间 - 因为在表单上输入的时间已转换为用户时区.抵消有效地取消了对方.

@document.created_at = Time.use_zone(@current_hotel.timezone) {Time.zone.parse("#{params[:document][:created_at]}").in_time_zone(@current_hotel.timezone)}
Run Code Online (Sandbox Code Playgroud)

我们基本上改变了Time对象的时区这里没有转换,时代对象的时候,时区变化的实际时间.(好运解析那句话!)

这看起来对我来说很好,但是我已经看了很久了,我很想看到更好的方式/更多Rails-ey这样做的方式!