【发布时间】:2015-03-03 13:09:00
【问题描述】:
我正在尝试了解时间戳的内容以及 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 不是一种选择。无论服务器上碰巧将哪个时区设置为系统时区,我都需要弄清楚如何处理这些事情。
【问题讨论】:
-
您使用的是哪个客户端?归根结底,一切都是平等的......而且在这里看小提琴:sqlfiddle.com/#!1/30ecd/1
-
@JorgeCampos:我从 postgre 附带的命令行 psql 客户端复制并粘贴了两个示例。在我的笔记本电脑上,我还使用了 GUI pgAdmin,它给出了相同的结果。太糟糕了,在 sqlfiddle 上没有时间戳设置。也许他们的系统时间设置为UTC,也许在这种情况下结果不同? (只是尝试将我的笔记本电脑时区设置为 UTC,在这种情况下,我得到与 sqlfiddle 相同的结果)
-
我发现这个问题stackoverflow.com/questions/9202857/… 与您的问题有关(不完全),可能与 GMT 和 CMT 有关。看看
标签: sql postgresql