【问题标题】:How to override Time.now with Time.zone.now in rails如何在 Rails 中用 Time.zone.now 覆盖 Time.now
【发布时间】:2018-08-01 10:02:40
【问题描述】:

你好,我正在做一个 Rails 项目。我想要特定区域的时间,我知道我可以使用Time.zone.now 但我想先设置区域,然后想根据区域获取时间。有什么方法可以让我在设置区域后用Time.zone.now 覆盖Time.now 方法。

我尝试在 application_controller.rb 中创建一个 before 操作,然后定义区域,但是每当我尝试访问 Time.now 时,它总是返回没有时区的时间。请帮我。提前谢谢。

application_controller.rb
def set_current_time_zone
  Time.zone = current_user.time_zone unless current_user.blank?
end

【问题讨论】:

  • Time 类中,覆盖now 方法,或者,只需添加返回timezone.nowwith_timezone 方法-))

标签: ruby-on-rails ruby timezone


【解决方案1】:

为什么不使用Time.current?如果您在config.zoneTime.zone 中设置了时区,它将给您时间。

看例子:

2.5.0 :021 > Time.zone = "Tallinn"
  => "Tallinn" 
2.5.0 :022 > Time.current
  => Wed, 21 Feb 2018 20:37:29 EET +02:00 
2.5.0 :023 > Time.zone = "New Delhi"
  => "New Delhi" 
2.5.0 :024 > Time.current
  => Thu, 22 Feb 2018 00:07:38 IST +05:30 

参见.current 方法的相应apidock 和thoughtbot 中关于Ruby 时区的好文章。

【讨论】:

  • 是的,兄弟,我同意,但我不想将 Time.now 更改为 Time.current,我想覆盖 Time.now,这样我就不必在任何地方进行更改。
【解决方案2】:

我就是这样做的,遵循 Ryan Bates 的 railscast:http://railscasts.com/episodes/106-time-zones-revised

class ApplicationController < ActionController::Base

  around_action :set_time_zone, if: :current_user

  def set_time_zone(&block)
    Time.use_zone(current_user.time_zone, &block)
  end

end

use_zone 方法需要一个块,并为该块的持续时间设置时区。请求完成后,原始时区会被调回。

然后,我可以使用 Time.zone.now,它将始终使用为用户设置的正确 time_zone(time_zone 方法返回用户在其设置中配置的时区或 UTC)。在控制器或模型中处理时,表单中的所有日期和时间字段也会按照当前用户的时区进行处理。

【讨论】:

  • 是的,我已经实现了相同的,但项目太大,我无法将 Time.now 替换为 Time.zone.now。我想将 Time.now 覆盖为 Time.zone.now,这样我就不必到处更改了
  • @awsmsid 如果您对 ruby​​ 核心库进行修补以产生不同的行为,那么您正在为任何其他加入该项目的人制造噩梦。不要那样做。只需使用您的 IDE 对整个项目进行 grep,然后将所有 Time.now 实例替换为 Time.zone.now
【解决方案3】:

希望这会有所帮助

module TimeOverride
  # overriding time to return time accoring to the application configured 
  #  timezone
  # instead of utc timezone
  def now
    super.getlocal(Time.zone.utc_offset)
  end
end

module DateTimeOverride
  # overriding time to return time accoring to the application configured 
  #timezone
  # instead of utc timezone
  def now
    Time.now.to_datetime
  end
end

Time.singleton_class.send(:prepend, TimeOverride)
DateTime.singleton_class.send(:prepend, DateTimeOverride)

【讨论】:

  • 如果有人正在寻找所发布问题的确切解决方案,请使用它。
猜你喜欢
  • 1970-01-01
  • 2011-02-04
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多