In my app I have a Person model. Each Person has an attribute time_zone that specifies their default time zone. I also have an Event model. Each Event has a start_time and end_time timestamp, saved in a Postgres database in UTC time.
I need to create a query that finds events for a particular person that fall between midnight of one day and midnight of the next. The @todays_events controller variable hold the results of the query.
Part of the reason that I’m taking this approach is that I may have people from other time zones looking at the list of events for a person. I want them to see the day as the person would see the day and not based on the time zone they are in as an observer.
For whatever reason, I’m still getting some events from the previous day in my result set for @todays_events. My guess is that I’m comparing a UTC timestamp with a non-UTC parameter, or something along those lines. Generally, only events that begin or end in the evening of the previous day show up on the query result list for today.
Right now, I’m setting up:
@today = Time.now.in_time_zone(@person.time_zone).midnight.to_date
@tomorrow = (@today + 1.day ).to_datetime
@today = @today.to_datetime
My query looks like:
@todays_activities = @person.marks.where("(start_time >= ? AND start_time < ?) OR (end_time >= ? AND end_time < ?);", @today, @tomorrow, @today, @tomorrow ).order("start_time DESC")
How should I change this so that I’m guaranteed only to receive results from today (per the @person.time_zone in the @todays_activities query?
You’re losing track of your timezones when you call
to_dateso don’t do that:When you
some_date.to_datetime, you get a DateTime instance that is in UTC so the result of something like this:will have a time-of-day of 00:00:00 and a time zone of UTC; the 00:00:00 is the correct time-of-day in
@person.time_zonebut not right for UTC (unless, of course,@personis in in the +0 time zone).And you could simplify your query with
overlaps:Note that
overlapsworks with half-open intervals: