Question

I have a scenario in which i get a timestamp and i need to search for all bookings for that date in that timestamp. The timestamp is in users respective timezone and all the records in the database are stored in UTC. so naturally i need to convert that timestamp back to UTC and then search.

Here's something that i'm doing:

Booking.where("date_time >= '#{DateTime.parse(timestamp).in_time_zone('UTC').beginning_of_day}' and date_time <= '#{DateTime.parse(timestamp).in_time_zone('UTC').end_of_day}'")

which basically means to fetch all bookings from the beginning of day till the end

However, when i use the following query it gives me a different result:

Booking.where("date_time >= '#{DateTime.parse(timestamp).beginning_of_day.in_time_zone('UTC')}' and date_time <= '#{DateTime.parse(timestamp).end_of_day.in_time_zone('UTC')}'")

I'm wondering which one is actually the correct statement to use in my use case and i would appreciate some input here.

Was it helpful?

Solution

I wouldn't use either one.

This one:

DateTime.parse(timestamp).in_time_zone('UTC').beginning_of_day

gives you the beginning of the UTC day, not the beginning of the local-time-zone-day offset to UTC. In short, it is incorrect and won't give you what you're looking for.

This one:

DateTime.parse(timestamp).beginning_of_day.in_time_zone('UTC')

is correct as it changes the time to the beginning of the day in the local time zone and then converts the timestamp to UTC.

If you let ActiveRecord deal with the quoting using a placeholder, then it will apply the UTC adjustment itself.

I'd also use < t.tomorrow.beginning_of_day rather than <= t.end_of_day to avoid timestamp truncation and precision issues; the end of the day is considered to be at 23:59:59.999... and that could leave a little tiny window for errors to creep in. I'm being pretty pedantic here, you might not care about this.

I'd probably do it more like this:

t = DateTime.parse(timestamp)
Booking.where('date_time >= :start and date_time < :end',
  :start => t.beginning_of_day,
  :end   => t.tomorrow.beginning_of_day
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top