在不同的 PostgreSQL 服务器上提取纪元的结果不同

Different results for extract epoch on different PostgreSQL servers

我们将时间戳转换为纪元,对它们进行一些计算,然后将它们转换回时间戳。数据库中的所有时间都是 TIMESTAMP WITHOUT TIME ZONE.

由于在英国这里切换到夏令时,时间在一个服务器上关闭了一个小时,但在另一个服务器上没有,所以我做了一个小测试:

SHOW SERVER_VERSION;
SHOW TIMEZONE;
SELECT extract(EPOCH FROM TIMESTAMP '1970-01-01');

在一台服务器上我得到

 server_version 
----------------
9.1.15
(1 row)

 TimeZone 
----------
GB
(1 row)

 date_part 
-----------
         0
(1 row)

但另一方面

 server_version 
----------------
9.3.6
(1 row)

 TimeZone 
----------
GB
(1 row)

 date_part 
-----------
     -3600
(1 row)

是否有任何可能导致此问题的服务器设置?

或者 extract 的行为在 Postgres 9.1 之后改变了吗?

是的,extract 的行为在 PostgreSQL 9.2 版中发生了变化。来自 the release notes:

  • Make EXTRACT(EPOCH FROM timestamp without time zone) measure the epoch from local midnight, not UTC midnight (Tom Lane)

    This change reverts an ill-considered change made in release 7.3. Measuring from UTC midnight was inconsistent because it made the result dependent on the timezone setting, which computations for timestamp without time zone should not be. The previous behavior remains available by casting the input value to timestamp with time zone.

这可能是造成差异的原因,因为根据 the docs

The SQL standard requires that writing just timestamp be equivalent to timestamp without time zone, and PostgreSQL honors that behavior.

正如@unique_id所建议的,使用timestamp with time zone(a.k.a。timestamptz)应该消除不一致。