为什么这个rails查询的行为取决于时区?

时间:2009-08-11 20:49:39

标签: ruby-on-rails datetime timezone dst

我有一个基于时间的rails查询,它有一些奇怪的时区敏感行为,即使据我所知我使用的是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

如果数据库确实包含在过去一小时内创建的一个模型,并且模型总数为280.因此只有第一个查询是正确的。

但是,在environment.rb中我有:

config.time_zone = 'UTC'

系统时区(由“日期”报告)是BST(GMT + 1) - 因此不知何故,这会被视为UTC并打破查询。

这引起了我各种各样的问题,因为我需要将在不同时间传递的查询参数化为一个动作(然后使用Time.parse()转换),即使我发送了UTC时间,这个'关闭一小时的DST问题就会产生很多影响。即使使用'.gmtime()'也似乎无法解决它。

显然,差异是由某个地方的隐式转换造成的,导致BST被错误地视为UTC,但为什么呢? rails是否以UTC格式存储时间戳? Time class timezone不是很清楚吗?我正在使用Rails 2.2.2

那么这里发生了什么 - 围绕它进行编程的安全方法是什么?

编辑,显示DB和Time类正在做什么的一些其他信息:

>> 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

3 个答案:

答案 0 :(得分:13)

Time类并不直接了解您配置的时区。 Rails 2.1增加了一堆时区支持,但Time仍然会对你当地的时区起作用。这就是Time.now返回BST时间的原因。

您可能想要的是与Time.zone进行互动。您可以像调用Time类本身一样调用方法,但它会在指定的时区内返回它。

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.hour1.hour.ago。它更容易阅读,Rails将自动使用配置的时区。

答案 1 :(得分:0)

您需要设置的TimeZone是UK,这将自动处理BST

Time.zone = 'UK'
Time.zone.now
 => Sun, 17 Oct 2010 02:09:54 BST +01:00

答案 2 :(得分:0)

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
相关问题