【问题标题】:Really odd issues with Time when it used within a scope在范围内使用 Time 时真的很奇怪
【发布时间】:2013-11-20 03:08:50
【问题描述】:

我的 Rails 应用中有一个页面应该显示游览,以便 start_date 字段等于明天的日期(在 GMT+00 中)

我在 application.rb 中使用默认时区

# Set Time.zone default to the specified zone and make Active Record ...
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'

但是有一个问题。我看到的是今天甚至昨天的日期,而不是显示从明天开始的巡演日期的页面。

我在页面上放了以下信息:

Time.zone                (GMT+00:00) UTC
Date.today_local_zone    2013-11-20
Date.today               2013-11-20
Time.now                 2013-11-20 00:48:21 +0000

我的控制器中的代码:

puts "... #{ Tour.upcoming.order('start_date ASC').to_sql }"
@tours = Tour.upcoming.order('start_date ASC')

以及 Tour 模型中的作用域

class Tour < ActiveRecord::Base 
  attr_accessible :start_date, :title
  scope :upcoming, where('tours.start_date > ?', Date.today_local_zone)
end

简单介绍一下我的 today_local_zone 方法:

class Date
  def self.today_local_zone
    Time.zone.now.to_date
  end
end

这是我的日志中的一行(查询日期与日志中的日期不同)

2013-11-20T00:48:21.178380+00:00 app[web.1]: ... SELECT "tours".* FROM "tours"  WHERE (tours.start_date > '2013-11-19') ORDER BY start_date ASC 
  • heroku restart 之后或部署日期有点正确
  • 在heroku 控制台heroku run rails c 中,所有日期也是正确的
  • 我决定从头开始另一个应用程序并部署在 heroku 上。结果保持不变。
  • 我每 5 分钟使用 pingdom ping 此页面。日期在午夜后一小时或两点甚至 23 点后变得正确。即滞后值每天都不同。

UPD:

我试图记录Time.zone.now.to_s.to_date 的值。它的值是正确的。

还请查看my gist 与:

  • 宝石文件
  • 网页屏幕截图,包括生成的查询的所有值和文本

【问题讨论】:

  • 您的 start_date 列的类型是什么?您的 ping 页面是否总是显示 UTC 的 Time.zone? Time.now 是否始终显示“+0000”,还是显示其他偏移量
  • 1) start_date 的类型是日期。 2) 是的。 3) 是的,Time.now 总是显示 '+0000'
  • 这里的 cmets - stackoverflow.com/questions/10099698/… - 可能是相关的。您是否有任何可以覆盖 to_date 的宝石?如果您将 Date#local_time_zone 方法更改为使用 Time.zone.now.to_s.to_date 会发生什么?
  • 这是我的 Gemfile gist.github.com/pyeremenko/7559892 。我创建了一个简单的应用程序来重现错误。所以 Gemfile 非常简单,而且我认为,没有任何宝石可以改变日期的行为。
  • Gemfile 中没有明显的内容。您是否尝试过我上面建议的to_s 选项?

标签: ruby-on-rails date heroku


【解决方案1】:

我在第一次审查时错过了这个。问题出在您的范围声明中:

scope :upcoming, where('tours.start_date > ?', Date.today_local_zone)

这个定义是错误的。它在加载类时加载 Date.today_local_zone。您需要将其包装在 Proc 中。所以应该是:

scope :upcoming, lambda { where('tours.start_date > ?', Date.today_local_zone) }

确保每次使用范围时都执行 Date.today_local_zone。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多