My server is in Central Time. I would like to render timestamps using Eastern time.
For instance, I would like to render 2012-05-29 15:00:00
as 2012-05-29 16:00:00 EDT
.
How can I achieve it?
to_char('2012-05-29 15:00:00'::timestamptz at time zone 'EST5EDT', 'YYYY-MM-DD HH24:MI:SS TZ')
gives 2012-05-29 16:00:00
(no zone).
to_char('2012-05-29 15:00:00'::timestamp at time zone 'EST5EDT', 'YYYY-MM-DD HH24:MI:SS TZ')
gives 2012-05-29 14:00:00 CDT
(wrong).
This one works, but it's so ridiculously complicated there must be an easier way: replace(replace(to_char(('2012-05-29 15:00:00'::timestamptz at time zone 'EST5EDT')::timestamptz, 'YYYY-MM-DD HH24:MI:SS TZ'), 'CST', 'EST'), 'CDT', 'EDT')
When dealing with a timestamp Postgres knows:
timezone
.timestamp
andtimestamptz
. (Or, to be precise: UT1.)When interpreting input, Postgres uses information about the provided time zone. When rendering a timestamp value, Postgres uses the current
timezone
setting, but time zone offset, abbreviation or name are only used to compute the correct value on input. They are not saved. It is impossible to extract that information later. More details in this related answer:Your "correct" example is almost correct.
TZ
ofto_char()
returns 'CDT' for timestamps that fall in the daylight saving periods of Central Time and 'CST' else. Eastern Time (EST
/EDT
) switches daylight saving hours at the same local time - I quote Wikipedia:The two time zones are out of sync during two hours per year. Of course, this can never affect a timestamp at
15:00
or16:00
, only around02:00
.A fully correct solution - much like what @Daniel already posted, slightly simplified:
The manual about
SET LOCAL
.The key is to switch the local timezone to the desired display timezone, for the duration of the transaction:
The result is:
Note that with
set [local] timezone
it is required to use full time zone names instead of abbreviations (for instance, CST would not work). Look up in thepg_timezone_names
view for valid choices.To use that method in a context similar to a to_char() call, I believe this function does the job: