分享 rails 日期查询容易进入的误区

hastings · 2013年04月13日 · 最后由 hastings 回复于 2013年06月06日 · 5621 次阅读

众所周知 mysql 的存储的数据中时间是跟当时时间差八小时的,我们正常引用时是不会出问题的,但当你试图对时间进行日期化查询时需要进行相应的处理 如我要查询今日的记录 错误的写法:Model.where("date(created_at) = ?",Date.today) 正确的写法:Model.where("date(date_add(created_at,interval 8 hour)) = ?",Date.today) 一般来说你对数据库进行时间查询,rails 会自动帮你作出处理,但这个处理只对时间形式的比较有效,对日期格式的比较是无效的。 以上面的写法为例,我要查询今天 (2013-4-13)7 点创建的一条数据 那么上面的查询语句就会变为 错误的写法:Model.where("date('2013-4-12 23:00:00') = ?", '2013-4-13') >> Model.where("'2013-4-12'= ?", '2013-4-13') 正确的写法:Model.where("date(date_add('2013-4-12 23:00:00',interval 8 hour)) = ?",'2013-4-13') >> Model.where("date('2013-4-13 7:00:00') = ?",'2013-4-13') => Model.where("'2013-4-13'= ?", '2013-4-13') 综上所述,在对 mysql 进行日期查询时要作出相应的加 8 小时的处理

获取开始和结束时间来查询,就不需要做时区转化,而且用 date 函数无法有效利用数据库索引。

Model.where("created_at >= ? and created_at <= ?", date.beginning_of_day, date.end_of_day)

#1 楼 @quakewang 好像在 SQL 使用了比较运算符都是无法利用数据库索引吧。

撸主为啥早上 7 点的数据 数据库存的却是前一天晚上 11 点?设置个时区不就好了么

where(:created_at => date.beginning_of_day.utc..date.end_of_day.utc)

看下生成的 SQL 时间对吗

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = 'Beijing'

# Store time of magic timestamps columns in local timezone, not UTC.
# The default setting is :utc which reset timezone of each database session to UTC.
config.active_record.default_timezone = :local

一般我在 config/application.rb 加上这两个配置

#5 楼 @clc3123 貌似加了你的第二个配置后,生成的新数据在数据库里时间还是减了八小时

需要 登录 后方可回复, 如果你还没有账号请 注册新账号