2

我对rails 3时区应该如何工作感到困惑。

所以我将rails配置为使用太平洋时间,并告诉活动记录以太平洋时间存储。

# application.rb
config.time_zone                      = 'Pacific Time (US & Canada)'
config.active_record.default_timezone = 'Pacific Time (US & Canada)'

现在我提交更新模型,这通过参数:

"start_at"=>"2013-07-24 00:00:00"

现在从控制台:

>> Sale.last
=> #<Sale id: 24, start_at: "2013-07-24 00:00:00", ...snipped... >

>> Sale.last.start_at
=> Tue, 23 Jul 2013 17:00:00 PDT -07:00

>> Sale.last.start_at.in_time_zone
=> Tue, 23 Jul 2013 17:00:00 PDT -07:00

因此,在尝试将所有内容强制为太平洋时间之后,它创建的时间对象通过考虑太平洋时间的 -7 小时来形成数据库。

如果我设定一个时间,2013-07-24 00:00:00我希望Tue, 24 Jul 2013 00:00:00 PDT -07:00会回来。然而事实并非如此。当活动记录使用 UTC 存储日期时,我遇到了类似的令人困惑的问题。我有一些测试只有在下午 5 点之后才会失败,因为时间到日期转换产生了不同的日期。

我该如何驯服这个?在数据库中存储 UTC 日期似乎是个好主意,我可以使用in_time_zone时间对象进行显示,但这是否意味着表单中的时间必须是 UTC?

我们的应用程序功能与服务器时间密切相关,并且某些事情每天都会在特定时间发生。因此,将所有内容强制到太平洋时间似乎应该没问题。但到目前为止,我似乎无法使这种行为始终如一。

我怎样才能让这一切都不糟糕?

4

1 回答 1

1

这将是一个 1/2 的答案,从上面的评论线程中重新迭代,并提供一些额外的信息

我希望以后更新更多。这个东西有很多陷阱

更新:终于在rails timezones上发表了一篇博文


我会使用 UTC 作为应用程序时区和 activerecord 默认值。使用 I18n.localize 方法(在 config/locales/en.yml 中设置格式)显示日期和日期时间;根据用户设置或默认值设置当前线程时区(对您的应用有意义的)


如果当前线程设置为用户时区 activerecord 应该做正确的魔法并将偏移 UTC 值保存在数据库中,然后当您使用 I18n 向用户显示该值时,它将在用户输入时显示它(从 UTC 转换到用户时区) - 当您输入一个时间以表示在另一个时区发生的事件时,它会变得有点棘手 - 在这种情况下,线程需要设置为该位置的时区并使用 I18n 显示需要是位置而不是用户


设置当前用户时区

一些代码

class ApplicationController < ActionController::Base
  protect_from_forgery

  # auth the user
  before_filter :authenticate_user!

  # Set user's time zone
  before_filter :set_user_time_zone

  # ....

  def set_user_time_zone
    if current_user and current_user.time_zone.present?
      Time.zone = current_user.time_zone
      # else some default?
    end
  end
end

或者 - 根据浏览器设置等设置...

http://guides.rubyonrails.org/i18n.html

具体来说: http: //guides.rubyonrails.org/i18n.html#setup-the-rails-application-for-internationalization

显示日期时间

使用I18n.localizeakaI18n.l或只是l- 请参阅http://guides.rubyonrails.org/i18n.html#adding-date-time-formats

更改部分视图的时区显示

用户设置为太平洋,但显示在东部发生的事件的事件时间

Time.use_zone(event.location.time_zone) do 
  puts event.start_time
end

警告:如果使用方法提取事件,我发现上述方法无法正常工作find_by_sql,常规活动记录查询工作良好

于 2013-07-24T17:31:09.790 回答