【发布时间】:2017-02-17 21:25:21
【问题描述】:
假设我有一个 Event 模型,其中有一个 date_time 字段表示活动举行的日期时间,我想查看所有举行的活动,比如“晚上 10 点之后”或“早上 7 点之前”多个日期。我怎么能这样做?
我的第一个想法是这样的:
scope :after_time ->(time){ where("events.date_time::time between ?::time and '23:59'::time", time) }
但这不起作用,因为日期以 UTC 格式存储并由 ActiveRecord 转换为应用程序的时区。
假设我正在搜索下午 5 点之后的活动,从我当地的阿德莱德时间开始。最终的查询是这样的:
WHERE (events.date_time::time between '2016-10-09 06:30:00.000000'::time and '23:59'::time)
也就是说,因为我的时区是 +10:30(阿德莱德时间),它现在正在尝试计算上午 6:30 到午夜之间,它确实需要找到在世界标准时间上午 6:30 到下午 1:30 之间创建的时间。
现在,特别是对于这个例子,我可能会一起破解一些东西来计算出“午夜”时间需要给出时区差异。但如果该时间段跨越世界标准时间午夜,between <given time> and <midnight in Adelaide> 计算将不起作用。所以这个解决方案是失败的。
更新:
我认为我已经设法通过反复试验获得了我想要的结果,但我不确定我是否完全理解发生了什么。
scope :after_time, ->(time) {
time = time.strftime('%H:%M:%S')
where_clause = <<-SQL
(events.date_time at time zone 'UTC' at time zone 'ACDT')::time
between ? and '23:59:59'
SQL
joins(:performances).where(where_clause, time)
}
它基本上把所有东西都变成了一个时区,所以每一行的查询最终看起来像WHERE '20:30:00' between '17:00:00' and '23:59:59',所以我不必担心跨越午夜的时间。
即便如此,我觉得可能有合适的方法来做到这一点,所以我愿意接受建议。
【问题讨论】:
标签: ruby-on-rails postgresql activerecord