方法一:EXTRACT
您可以使用EXTRACT 从order_date 获取小时:
Order.where('EXTRACT(hour FROM order_date) BETWEEN ? AND ?', 7, 20)
请注意,我将 20(晚上 8 点)指定为上限。如果我使用21,那么order_date 与21:30 的时间部分将匹配,这不是我们想要的。
您可以将上面的查询包装在一个范围内:
class Order < ActiveRecord::Base
scope :between, -> (start_hour, end_hour) {
where('EXTRACT(hour FROM order_date) BETWEEN ? AND ?', start_hour, end_hour - 1)
}
end
您可能还想解决一些其他问题,例如检查 start_hour 和 end_hour 的有效值(例如,一小时 -1 无效)。
此方法很简单,但仅限于整小时(您可以添加分钟和秒,但该方法会变得复杂)。
方法 2:显式转换为 time
Ruby 中的
Time 存储日期 和 时间。例如:
Time.parse('15:30:45') # => 2017-01-02 15:30:45 +0100
您可以将 Time 传递给 PostgreSQL 并将其强制转换为 Postgres time 类型:
class Order < ActiveRecord::Base
scope :between, -> (start_time, end_time) {
where('order_date::time BETWEEN ?::time AND ?::time', start_time, end_time)
}
end
这种方法的优点是灵活性。缺点是在 UI 中处理时间有点复杂。范围需要一对 Time 对象。获取方式有很多种,例如:Time.parse('12:17')。