Unix 时间戳是自 1970 年 1 月 1 日午夜 UTC 以来的秒数。
如何从 PostgreSQL 获取正确的 unix 时间戳?
与currenttimestamp.com和timestamp.1e5b.de进行比较时,我没有从 PostgreSQL 获得预期时间:
这将返回正确的时间戳:
SELECT extract(epoch from now());
虽然这不是:
SELECT extract(epoch from now() at time zone 'utc');
我住在 UTC +02 时区。从 PostgreSQL 获取当前 unix 时间戳的正确方法是什么?
这将返回正确的时间和时区:
SELECT now();
now
-------------------------------
2011-05-18 10:34:10.820464+02
另一个比较:
select now(),
extract(epoch from now()),
extract(epoch from now() at time zone 'utc');
now | date_part | date_part
-------------------------------+------------------+------------------
2011-05-18 10:38:16.439332+02 | 1305707896.43933 | 1305700696.43933
(1 row)
Unix timestamp from the web sites:
1305707967
在 postgres 中,
timestamp with time zone
可以缩写为timestamptz
, 和timestamp without time zone
astimestamp
。为简单起见,我将使用较短的类型名称。timestamptz
正如您所说,从 postgres 获取Unix时间戳now()
很简单,只需:这就是你需要知道的关于从任何类型中获取绝对时间的全部信息
timestamptz
,包括now()
.timestamp
只有当你有一个领域时,事情才会变得复杂。当您将
timestamptz
类似数据now()
放入该字段时,它将首先转换为特定时区(显式使用at time zone
或通过转换为会话时区),并且时区信息被丢弃。它不再指绝对时间。这就是为什么您通常不想像timestamp
通常使用的那样存储时间戳的原因——也许一部电影会在每个时区timestamptz
的特定日期的下午 6 点上映,这就是这种用例。如果您只在一个时区工作,您可能会(误)使用
timestamp
. 转换回timestamptz
足够聪明以应对 DST,并且为了转换目的,假设时间戳位于当前时区。以下是 GMT/BST 的示例:DBFiddle
但是,请注意以下令人困惑的行为:
DBFiddle
这是因为:
不会返回正确的时间戳,因为 postgres 时区转换会从结果中丢弃时区信息:
之后,extract 会查看没有时区的时间戳,并认为它是本地时间(尽管实际上它已经是 utc)。
正确的方法是:
在最后一行中,第一个
at time zone
执行转换,第二个为结果分配新的时区。