微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我有一个基于时间的rails查询,它有一些奇怪的时区敏感行为,即使据我所知我使用的是UTC.简而言之,这些查询给出了不同的答案:
>> Model.find(:all,:conditions=>['created_at<=?',(Time.Now-1.hours).gmtime]).length
=> 279
>> Model.find(:all,(Time.Now-1.hours)]).length
=> 280

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

但是,在environment.rb中,我有

config.time_zone = 'UTC'

系统时区(由“日期”报告)是BST(格林威治标准时间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

解决方法

Time类不直接了解您配置的时区. Rails 2.1增加了一堆时区支持,但时间仍然会对你当地的时区起作用.这就是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.hour do 1.hour.ago.它更容易阅读,Rails将自动使用配置的时区.

原文地址:https://www.jb51.cc/ruby/270647.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐