I am trying to understand what is going in with timestamps and how postgreSql handles time zones and have been remarkable unsuccessful.
Here is and example script I created to learn:
drop table if exists timestampTest;
create table timestampTest(
ts timestamp with time zone
);
insert into timestampTest (ts) values (to_timestamp(0) at time zone 'utc');
select
to_timestamp(0) at time zone 'utc' INSERTED,
ts at time zone 'utc' RETRIEVED_UTC,
ts RETRIEVED_DEFAULT,
extract(epoch from ts) RETRIEVED_TS_DEFAULT,
extract(epoch from ts at time zone 'utc') RETRIEVED_TS_UTC,
extract(epoch from to_timestamp(0) at time zone 'utc') INSERTED_TS
from timestampTest
When I run the script on my Laptop (PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
) with german time it outputs:
inserted | retrieved_utc | retrieved_default | retrieved_ts_default | retrieved_ts_utc | inserted_ts
---------------------+---------------------+------------------------+----------------------+------------------+-------------
1970-01-01 00:00:00 | 1969-12-31 23:00:00 | 1970-01-01 00:00:00+01 | -3600 | -3600 | 0
Which stuns me, because I expected inserted
and retrieved_utc
to be the same because the only difference that I can see is that once the value was stored in a table and then loaded which should not change the value (should it?).
Additionally I expected all timestamp values to be the same (seconds since begin of unix epoch UTC). The value I least expected to differ from the others was inserted_ts
. However it indeed differs. Why?
Then, more by accident than by purpose I executed the script on a server I am running (PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
) which is also located in Germany and has its time set to German time. It gives the following result:
inserted | retrieved_utc | retrieved_default | retrieved_ts_default | retrieved_ts_utc | inserted_ts
---------------------+---------------------+------------------------+----------------------+------------------+-------------
1970-01-01 00:00:00 | 1969-12-31 23:00:00 | 1970-01-01 00:00:00+01 | -3600 | -7200 | -3600
What actually happened here?
UPDATE: I just tried to set the system time to UTC on my Laptop. In this case I get the desired result:
inserted | retrieved_utc | retrieved_default | retrieved_ts_default | retrieved_ts_utc | inserted_ts
---------------------+---------------------+------------------------+----------------------+------------------+-------------
1970-01-01 00:00:00 | 1970-01-01 00:00:00 | 1970-01-01 01:00:00+01 | 0 | 0 | 0
And YAY, that's a result I would actually expect and not be astounded by (well, I am astounded that retrieved_default
is still displayed in German time, but at least it is still refering to the same point in time). But setting the time zone of my computers permanently to UTC is not an option. I need to figure out how to deal with these things no matter which time zone happens to be set on the server as system time zone.