转换Rails ActiveRecord时间戳的时区

时间:2019-04-21 23:06:17

标签: ruby-on-rails ruby activerecord timezone

我在Rails项目中扩展了Time类,因此我可以轻松地在NYC获得时间:

/lib/extensions.rb

class Time
  # Get NYC time:
  def nyc
    self.in_time_zone('Eastern Time (US & Canada)')
  end
end

进行测试,看起来不错:

time_a = Time.now.utc.nyc
=> Sun, 21 Apr 2019 18:42:12 EDT -04:00

问题是当我从数据库中获取时间戳时:

time_b = object.created_at.in_time_zone('Eastern Time (US & Canada)')
=> Sun, 21 Apr 2019 17:22:04 EDT -04:00
time_c = object.created_at.nyc
=> Sun, 21 Apr 2019 17:22:04 UTC +00:00

超级困惑。当我在控制台中使用in_time_zone时,将时间戳转换为EDT是可行的,但是当我使用扩展名时却不能?即使我的扩展方法适用于在控制台中创建的Time对象?这是怎么回事?


注意:Rails中的时间实例实际上是ActiveSupport::TimeWithZone的实例。“ TimeWithZone实例实现与Ruby Time实例相同的API,因此Time和TimeWithZone实例可以互换。” -ActiveSupportTimeWithZone

1 个答案:

答案 0 :(得分:1)

您需要修补ActiveSupport :: TimeWithZone而不是时间,例如

class ActiveSupport::TimeWithZone
  def nyc
    in_time_zone('Eastern Time (US & Canada)')
  end
end

Time.zone.now.nyc # => Mon, 22 Apr 2019 06:44:41 EDT -04:00
User.last.created_at.nyc # => Sun, 21 Apr 2019 13:34:45 EDT -04:00

https://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html

(编辑:我之前说过“ DateTime”而不是“ ActiveSupport :: TimeWithZone”)