Rails 3.0.20 应用程序上的 Ruby 升级(从 1.8.7 开始)导致时区异常

Posted

技术标签:

【中文标题】Rails 3.0.20 应用程序上的 Ruby 升级(从 1.8.7 开始)导致时区异常【英文标题】:Ruby upgrade (from 1.8.7) on Rails 3.0.20 application causing time zone weirdness 【发布时间】:2014-09-05 17:58:18 【问题描述】:

我正在升级一个又大又旧又笨重的 Rails 应用程序的 Ruby(主要是这样我就不必在重新格式化的笔记本电脑上重新安装 REE),而且我被时区问题严重困扰。基本上,从数据库中提取日期时间并不能正确地将它们转换为本地时间:

新系统 - Ruby 2.1.2、Ubuntu 14.04

>> Time.zone.name
=> "Central Time (US & Canada)"
>> ActiveRecord::Base.time_zone_aware_attributes
=> true
>> ActiveRecord::Base.default_timezone
=> :utc
>> Transaction.last.created_at
=> 2014-07-15 02:09:02 UTC
>> Transaction.last.created_at_before_type_cast
=> 2014-07-15 02:09:02 UTC
>> Transaction.last.created_at.localtime
=> 2014-07-14 21:09:02 -0500
>> exit
$ date
Mon Jul 14 22:27:50 CDT 2014

旧系统 - REE、Ubuntu 12.04

>> Transaction.last.created_at
=> Mon, 14 Jul 2014 22:03:11 CDT -05:00
>> Transaction.last.created_at_before_type_cast
=> Tue Jul 15 03:03:11 UTC 2014
>> Transaction.last.created_at.localtime
=> Mon Jul 14 22:03:11 -0500 2014

如您所见,我确保设置了time_zone_aware_attributes,设置了区域(我在 environment.rb 中设置了它),并且 ActiveRecord 以 UTC 格式存储时间(正如预期的那样)。我对此感到很困惑。有人有什么想法吗?

更新

  before :all do
    @current_tz = Time.zone
    Time.zone = 'Pacific Time (US & Canada)'
  end

  after :all do
    Time.zone = @current_tz
  end

  it 'should report time as Pacific time' do
    shift = FactoryGirl.create(:shift)
    new_obj = Transaction.create(shift: shift, time: DateTime.new(2013, 3, 31, 0, 0, 0, 0), amount: 0)
    new_obj.reload
    I18n.localize(new_obj.time, format: :timeonly).should_not == '12:00 am' #We created it with a UTC date, but it should get I18n'd to Pacific time
  end

#en.yml
  time:
    formats:
      timeonly: "%l:%M %p"

上述测试失败了。 I18n 的东西似乎完全坏掉了。

更新 2

我似乎已将问题隔离到 1.9.3 -> 2.1。我想使用 1.9.3 很好,我想我会在新服务器上运行它,直到升级 Rails。伤心。我仍然很想听听有关修复的任何建议。

【问题讨论】:

我在 ruby​​ 2.1 和 rails 4.0 上运行了你的代码,i18n 的输出是 5:00。也许是 rails 3.0.x 和 ruby​​ 2.1 不兼容?与 ruby​​ 2.0 完全兼容的最早版本的 rails 类似于 3.2.16,所以当您将 rails 3.0 与 ruby​​ 2.1 结合使用时,如果出现一些问题,我不会感到非常惊讶 正确。有几个补丁(一个与 AR 关联被破坏有关)我不得不使用它们来尝试让它们兼容,但是这个非常令人惊讶。将项目从 3.0 升级到 3.2(或 4)并不是我现在真正有时间的事情......所以我放弃了让它在 Ruby 2 上运行的目标。=)谢谢! 【参考方案1】:

尝试使用 I18n 助手来格式化/偏移您的时间输出 - 并强制时区(如果需要)

puts I18n.localize(Transaction.last.created_at, format: :long)

或者

Time.use_zone("Central Time (US & Canada)") do
  puts I18n.localize(Transaction.last.created_at, format: :long)
end

我建议您也将默认 Time.zone 设置为 UTC,并根据需要为每个用户明确更新它 - 这里有一篇博文可能会有所帮助:http://jessehouse.com/blog/2013/11/15/working-with-timezones-and-ruby-on-rails/

【讨论】:

谢谢,从长远来看,这可能是件好事,但对于 Ruby 升级来说绝对是出乎意料的......这个网站是针对本地市场的,所以所有用户/操作都在一个时区,但是我熟悉所有按用户设置时区的做法。 此外,重建此应用程序的所有视图以使用这样的本地化时间并不容易。

以上是关于Rails 3.0.20 应用程序上的 Ruby 升级(从 1.8.7 开始)导致时区异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 5 上的 ruby​​ 中添加人脸识别?

Google App Engine 上的 Ruby on Rails 应用程序

被阻止的主机:rails 6.0.0 上的 localhost ruby

Ruby on Rails - Heroku上的Carrierwave错误

Amazon ElasticBeanstalk 上的 Ruby on Rails 部署:签名过期错误

Ruby 2.0.0,而不是 Rails 网站上的 2.1.0 推荐?