ruby-on-rails - 为什么这个 rails 查询的行为会因时区而异?

标签 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 时间发送,这个“关闭一小时” ' 夏令时问题很多。即使使用 '.gmtime()' 似乎并不总是能解决它。

显然,这种差异是由某处的隐式转换引起的,导致 BST 被错误地视为 UTC,但为什么呢? rails 不以 UTC 格式存储时间戳吗?时间类时区不知道吗?我正在使用 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 class 不直接知道您配置的时区。 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 将自动使用配置的时区。

关于ruby-on-rails - 为什么这个 rails 查询的行为会因时区而异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1262825/

相关文章:

ruby-on-rails - 在 Rails 中查找具有多个外键值的记录

ruby-on-rails - 多列索引的 Rails 迁移 - 如何命名索引?

javascript - 使用日期序列化 json 对象 - javascript

java - 夏令时 至 标准时区

ruby-on-rails - Searchkick 结果的未定义方法分页

ruby-on-rails - 如何在 Coffeescript 中导入 js 文件?

MYSQL - 如果选择日期中没有行,如何设置零

php - 如何将日期时间转换为字符串?

java - 当 java 代码以 UTC 执行时,如何在 ET 中存储一个带有偏移量的日期

django - 对如何根据本地用户时间定制日期时间模板演示感到困惑