Timezone aware postgres query create a timeseries for minutes, hours, days

Viewed 279

I am having a hard time to figure out how to deal with the following problem:

Our company is publishing posts to social media platforms. Those posts are stored within the database once they where successfully postet.

We want to provide a dashboard showing an overview of how many posts the user published over a time period grouped by minutes, hours and days.

I want to display the results as a time series graph.

This would work fine, but it gets very tricky once I have to support multiple time zones when I do aggregation/grouping by days. (apparently posts around midnight belong to different days depending on which time zone you are)

My current solution builds the postgres query using rails ActiveRecord. The problem I am facing is that I am struggling to deal with the timezone conversions... Also I am not particular good at postgres... The current implementation essentially looks like this (I removed irrelevant code):

Publication.select(                                                                                                                                                         
    %{date_trunc('#{interval}',
      published_at::timestamptz at time zone interval '#{time_zone_offset}')::timestamptz as time,
      count(published_at)})
      .where(%(published_at BETWEEN
          timestamptz '#{start_date}' AND
          timestamptz '#{end_date}'))
          .group("1")
          .order('time').limit(LIMIT)

For example:

I have one publication at 2016-03-15 10:19:24.219258 (Thats how it is stored inside the database therefore UTC time) I create the following query:

SELECT  date_trunc('hour',
      published_at::timestamptz at time zone interval '+01:00')::timestamptz as time,
      count(published_at) FROM "publications" WHERE (published_at BETWEEN
          timestamptz '2016-03-15 10:00:00 +0100' AND
          timestamptz '2016-03-15 12:00:00 +0100') GROUP BY 1 
;

Which results in:

          time          | count 
------------------------+-------
 2016-03-15 10:00:00+01 |     1
(1 row)

Which should be:

time: "2016-03-15 10:00:00 UTC" or "2016-03-15 11:00:00+01" ( i don't care about the time zone representation but this is simply the wrong result)

Anybody knows what I am doing wrong here?

The main problem I got stuck is that I want to be able to group/aggregate publications per day, with respect to the time zone of the user requesting the query. I don't care which time zone is returned as the front end can transform it to the user time zone.

Any feedback, help, or answer is highly appreciated. Many thanks

1 Answers
Related