在我的应用中,我有一个Person模型。 每个Person都有一个time_zone属性,用于指定其默认时区。 我也有一个Event模型。 每个Event都有一个start_timeend_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 < ?) OR (end_time >= ? AND end_time < ?);", @today, @tomorrow, @today, @tomorrow ).order("start_time DESC")

我应该如何更改此设置,以保证只能收到今天的结果(根据@todays_activities查询中的@person.time_zone @todays_activities

===============>>#1 票数:10 已采纳

当您致电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正确的一天中的@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 ,除非start和end相等,在这种情况下,它代表那个单个时刻。

  ask by Clay translate from so

未解决问题?本站智能推荐: