tl;dr
Postgres adjusts all TIMESTAMP WITH TIME ZONE
inputs to UTC, an offset of zero. Retrieved values remain in UTC, an offset of zero.
If you need the original offset, record that info in another column.
Offset versus Zone
To clarify terms…
- An offset is merely a number of hours-minutes-seconds ahead or behind the temporal meridian of UTC. That meridian is basically where the sun at noon is directly overhead the Royal Observatory, Greenwich.
- A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region as decided by their politicians.
Postgres adjusts to UTC (offset of zero)
timestamp with timezone column'2012-08-24 14:00:00+03:00' and after trying to do a select i'm getting '2012-08-24 11:00:00+00
As you have seen, and as documented, for a column of type TIMESTAMP WITH TIME ZONE
, Postgres uses the input’s offset-from-UTC to adjust to an offset of zero hours-minutes-seconds.
Your offset indicates a time of 14:00 with an offset of 3 hours ahead of UTC. So Postgres adjusts the time to 11:00 with an offset of zero. Same moment, same point on the timeline, different perspective.
Beware of tooling with auto-adjust anti-feature
Postgres retrieves the stored value with its offset of zero.
Unfortunately, many tools choose to dynamically apply some default time zone onto the retrieved value. While well-intentioned, this anti-feature confuses the picture, creates an illusion that the moment was stored with a particular time zone or offset. But, no, in Postgres values in a TIMESTAMP WITH TIME ZONE
are always stored in UTC (offset of zero), and always retrieved in UTC (offset of zero).
Behavior varies across database engines
The SQL standard barely addresses date-time issues. So much of date-time handling behavior in various databases is implementation-specific.
Some other database engines do the same as Postgres, auto-adjusting to an offset of zero. But some database engines may not. Always study the doc.
Store offset in another column
If knowing the original offset is important to you, you’ll need to save that fact as a value in another column. I would suggest a column of a textual type, storing offset values in standard ISO 8601 format.
timestamptz
type. If you want to do this then you need to use thetimestamp
type for the timestamp value and a separate column for the offset/timezone . – Mccartneytimestamptz
does not store the time zone it just rotates the timestamp to a UTC value for storage. It then rotates the value from UTC to whatever is the controllingtimezone
value is at the time. See 8.5.1.3. Time Stamps here Datetime Types for more information. – Mccartneytimestamptz
if your source data comes with timezone offsets. – Barcot