Rails 3.1:在一个时间范围内查询Postgres的记录
在我的应用程序中,我有一个Person
模型。 每个Person
都有一个属性time_zone
,用于指定其默认时区。 我也有一个Event
模型。 每个Event
都有一个start_time
和end_time
时间戳,以UTC时间保存在Postgres数据库中。
我需要创建一个查询,查找特定人员在一天的午夜和下一个午夜之间的事件。 @todays_events
控制器变量保存查询结果。
我采用这种方法的部分原因是我可能让其他时区的人查看一个人的事件列表。 我希望他们看到这一天,因为这个人会看到这一天,而不是基于他们作为观察者所在的时区。
无论出于何种原因,我仍然在前一天的@todays_events.
结果集中收到一些事件@todays_events.
我的猜测是我将UTC时间戳与非UTC参数进行比较,或者沿着那些线进行比较。 通常,只有在前一天晚上开始或结束的事件才会显示在今天的查询结果列表中。
现在,我正在建立:
@today = Time.now.in_time_zone(@person.time_zone).midnight.to_date @tomorrow = (@today + 1.day ).to_datetime @today = @today.to_datetime
我的查询看起来像:
@todays_activities = @person.marks.where("(start_time >= ? AND start_time = ? AND end_time < ?);", @today, @tomorrow, @today, @tomorrow ).order("start_time DESC")
我应该如何改变这一点,以便我保证只收到今天的结果(根据@todays_activities
查询中的@person.time_zone
@todays_activities
?
当你调用to_date
时,你正在失去对时区的追踪,所以不要这样做:
@today = Time.now.in_time_zone(@person.time_zone).midnight.utc @tomorrow = @today + 1.day
当你some_date.to_datetime
,你得到一个UTC的DateTime实例,所以结果是这样的:
Time.now.in_time_zone(@person.time_zone).midnight.to_date.to_datetime
将有一个00:00:00的时间和UTC的时区; 00:00:00是@person.time_zone
正确的时间,但不适合UTC(当然,除非@person
位于+0时区)。
您可以使用overlaps
来简化查询:
where( '(start_time, end_time) overlaps (timestamp :today, timestamp :tomorrow)', :today => @today, :tomorrow => @tomorrow )
请注意, overlaps
以半开间隔工作 :
每个时间段被认为代表半开间隔
start <= time < end
,除非开始和结束相等,在这种情况下它代表单个时刻。