In my phoenix application, I've been using Ecto with Timex to store my dates in postgres. When I show results to the end user, I show days in reverse order (i.e. today is at the top of the list) and then sort results in each day chronologically.
For this to work properly, I need to apply the users timezone before processing the sort. What I've been doing (until now) is retrieve the data, converting the dates using Timex and then run the sorting client-side. For example, I might do something like this:
tz_user = Timex.Timezone.get( "Australia/Hobart", Timex.now )
captains_log = CaptainsLog.list_logs_for_user( current_user )
days = captains_log
|> Enum.map( fn (log) -> %Log{ log |
star_date: Timex.Timezone.convert( log.star_date, tz_user ),
end_transmission: Timex.Timezone.convert( log.end_transmission, tz_user )
} end)
|> Enum.group_by( fn ( log ) -> Timex.to_date(log.end_transmission) end )
|> Enum.sort( fn (e1, e2) ->
{ date1, _ } = e1
{ date2, _ } = e2
Timex.compare( date1, date2 ) >= 0
end)
However, now I'd like to achieve this server-side. If I do something like the following:
select star_date at time zone 'AEST' from captains_log;
The date is not adjusted for my time zone (as I had assumed would be the case). For example, "8:48am" was stored in the database as "9:48pm" and appears as "11:48am" in the above select statement. AEDT isn't much better, the result is "10:48am".
Here's what star_date and end_transmission looks like in the schema:
field :star_date, Timex.Ecto.DateTime
field :end_transmission, Timex.Ecto.DateTime
When records are added to the database, star_date is set to the last end_transmission. end_transmission is typically set to Timex.now.
So how are dates/times stored in postgres by Ecto? Can I write a server-side query that adjusts to the desired timezone? The timezone for each user may be different, what can I pass up to postgres so I can make the query work for different time zones?