我正在尝试了解时间戳的内容以及postgreSql如何处理时区并且非常不成功。
这是我创建的示例脚本:
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
当我使用德语时间在我的笔记本电脑上运行脚本(PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
)时,它会输出:
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
让我感到震惊,因为我期望inserted
和retrieved_utc
是相同的,因为我能看到的唯一区别是,一旦将值存储在表中然后加载哪个不应该更改价值(应该吗?)。
此外,我希望所有时间戳值都相同(自unix时代UTC开始以来的秒数)。我最不希望与其他人的差异是inserted_ts
。然而它确实不同。为什么呢?
然后,更多的是偶然而非目的我在我正在运行的服务器(PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
)上执行了脚本,该服务器也位于德国并且其时间设置为德国时间。它给出了以下结果:
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
这里到底发生了什么?
更新:我刚尝试在笔记本电脑上将系统时间设置为UTC。在这种情况下,我得到了所需的结果:
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
而且,是的,这是我真正期待的结果,而不是被惊呆了(好吧,我很惊讶retrieved_default
仍然在德国时间显示,但至少它仍然指向同一时间点)。但是,将计算机的时区永久设置为UTC不是一种选择。无论在服务器上将哪个时区设置为系统时区,我都需要弄清楚如何处理这些事情。
答案 0 :(得分:1)
当您在时区'UTC'使用to_timestamp(0)插入时,“at time zone”部分会从返回类型中删除时区,从而以“local”结尾,然后重新转换回UTC插入时您不需要在插入语句中使用“at time zone'utc'”。
要更好地了解正在发生的事情,请尝试以下操作:
set timezone='America/Chicago';
select to_timestamp(0), (to_timestamp(0) at time zone 'UTC') at time zone 'UTC'