【问题标题】:Rails : Given that my database is in UTC, and my Time.zone US Eastern, how do I save a time in US Pacific?Rails:鉴于我的数据库是 UTC 和我的 Time.zone 美国东部,我如何在美国太平洋节省时间?
【发布时间】:2012-04-19 07:47:11
【问题描述】:

(我在 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

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

【问题讨论】:

    标签: ruby-on-rails ruby time timezone


    【解决方案1】:

    datetime 列类型仅存储日期和时间,但不存储时区。您可能需要创建一个辅助列来保留用于解释保存在那里的 UTC 时间的时区。

    这两个值可以结合起来重新创建您的初始输入。

    【讨论】:

    • 我猜,但我不想存储时区。这是额外的开销,我很高兴只使用 UTC。我只是想让 Rails 内部人员知道“这条数据使用的偏移量与我的全局 Time.zone 不同,因此请以不同的方式调整为 UTC。”
    • 那能不能用in_time_zone的方法在保存之前转换一下?
    • 我现在实际上正在查看它,但我无法将我的参数编组到 Time 对象中。来自 params 对象的字符串没有偏移量,每次我尝试编组它时,新实例化的时间对象都基于本地机器的时区,因此使用 in_time_zone 进行的任何转换都是不正确的。有什么想法吗?!
    • 您可能希望直接构造一个 DateTime 对象,因为您可以提供的参数之一是时区偏移量。我不确定 Time 是否强大。
    • 我昨天实际上试图在这里发布我的解决方案作为答案,但我是新手,它不会让我这样做。我现在就做!
    【解决方案2】:

    破解了!

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

    然后,我们通过使用酒店的时区而不是用户的时区,向该方法传递一个块,在该块中我们生成 Rails 期望的值。这意味着 Rails 转换为 UTC 会在 db 中产生正确的时间 - 因为在表单上输入的时间已转换为用户时区。偏移量有效地相互抵消了。

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

    我们基本上是在此处更改 Time 对象的时区而不在时区更改时转换该 Time 对象的实际时间。(祝你好运解析那句话! )

    这看起来对我来说工作得很好,但我已经研究这个太久了,我很想看到一个更好的方式/更多的 Rails-ey 方式来做到这一点!

    【讨论】:

    • 我不明白这方面缺乏问答...我花了几个小时寻找这个...这当然很常见?或者从字面上看,当您扩展到跨地理区域时,您会在轨道之外切换?呃...非常感谢你这样做!
    猜你喜欢
    • 2022-06-29
    • 1970-01-01
    • 2021-09-05
    • 2019-04-16
    • 1970-01-01
    • 2018-09-07
    • 2021-05-30
    • 2015-12-31
    • 1970-01-01
    相关资源
    最近更新 更多