为什么会出现这种导轨查询不同的表现取决于时区?
-
13-09-2019 - |
题
有我其中有一些奇怪的时区敏感的行为基于时间的轨道查询,即使因为据我所知,我使用UTC。概括地说,这些查询给出不同的答案:
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours).gmtime]).length
=> 279
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours)]).length
=> 280
凡DB实际上确实包含在最后一小时内创建一个模型,模型的总数是280因此,只有第一个查询是正确的。
然而,在environment.rb中我有:
config.time_zone = 'UTC'
(所报告的“日期”)的系统时区是BST(这是GMT + 1) - ,以便以某种方式本卷起得到视为UTC和断裂的问题。
这是导致我的各种问题,因为我需要参数化查询传递不同的时间向一个动作,并且即使在我UTC的时间发送,这种“断(其然后使用Time.parse()转换)一个小时的DST问题庄稼了很多。甚至使用“.gmtime()”并不总是似乎解决它。
显然的差被以某种方式由某处导致BST的隐式转换引起的被错误地视为UTC,但为什么呢?不轨存储UTC时间戳?还不是时候类时区知道?我使用的Rails 2.2.2
那么,什么是怎么回事 - ,什么是它周围的编程安全的方式?
修改,一些额外的信息显示什么的DB和时间类是做:
>> Model.find(:last).created_at
=> Tue, 11 Aug 2009 20:31:07 UTC +00:00
>> Time.now
=> Tue Aug 11 22:00:18 +0100 2009
>> Time.now.gmtime
=> Tue Aug 11 21:00:22 UTC 2009
解决方案
在Time
类不直接了解您的配置的时区的。 Rails的2.1添加了一堆的时区的支持,但仍Time
将在您的本地时区行事。这就是为什么Time.now返回BST时间。
您可能想要的是与Time.zone
互动。您可以拨打像你这个方法将时间类本身,但它会在指定的时间段返回。
Time.zone.now # => Tue, 11 Aug 2009 21:31:45 UTC +00:00
Time.zone.parse("2:30 PM Aug 23, 2009") # => Sun, 23 Aug 2009 14:30:00 UTC +00:00
你必须要小心的另一件事情是,如果你做的查询数据库,你是比较次,但一定要使用UTC时间(即使你有指定一个不同的时区)由于Rails总是存储UTC在数据库中。
Item.all(:conditions => ["published_at <= ?", Time.now.utc])
此外,取代Time.now-1.hour
做1.hour.ago
。这是更容易阅读和Rails会自动使用配置的时区。
其他提示
您需要设置时区是英国,这将自动处理BST
Time.zone = 'UK'
Time.zone.now
=> Sun, 17 Oct 2010 02:09:54 BST +01:00
start_date_format = DateTime.strptime(@start_date, date_format)
start_date_format_with_hour =
DateTime.strptime((start_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)
end_date_format = DateTime.strptime(@end_date, date_format)
end_date_format_with_hour = DateTime.strptime((end_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)
@filters_date = "invoices.created_at >= ? AND invoices.created_at < ?", start_date_format_with_hour, end_date_format_with_hour