【发布时间】:2018-03-22 05:35:48
【问题描述】:
我正在开发一个系统,我正在尝试最大限度地减少时区可能引入的错误,因此我在 (postgresql) 数据库上使用时间戳字段,但我在创建记录时使用 UNIX 纪元的秒数和当我读取记录时(使用EXTRACT(EPOCH)读取,插入时使用TO_TIMESTAMP())。
这样我就可以摆脱时区问题。我还是这样。经过一番挖掘后,我发现从表中读取值时,postgresql 变得有点困惑。考虑这个查询:
select current_timestamp, extract(EPOCH from current_timestamp), id, last_gps_read,
extract(EPOCH from current_timestamp) - extract(EPOCH
from last_gps_read) from sometable where id=1
这给了
now | date_part | id | last_gps_read | ?column?
-------------------------------+------------------+----+--------------------------+-----------------
2018-03-21 23:26:07.263931-06 | 1521696367.26393 | 1 | 2018-03-21 23:26:00.5273 | 21606.736631155
请注意日期之间的距离非常接近(仅相差大约 7 秒?)。
所以当我使用 extract(EPOCH from x) 技巧时,我认为差异会给我大约 7 秒....而不是我得到〜21607(我在 GMT-6 上,这解释了为什么它是 21600秒的差异)。这绝对不是很酷,因为这意味着当报告两个日期的 UNIX 纪元以来的秒数时,它在报告来自表的数据的秒数时以某种方式引入了时区(我刚刚检查了 current_timestamp 的 UNIX 纪元以来的秒数是正确的)。
这样做的原因是什么?因为这对我来说听起来很像一个错误。
PS 我可以考虑将数据库上的字段类型更改为使用整数来保存自 UNIX 纪元以来的实际秒数,因此我肯定会摆脱它,但这听起来有点矫枉过正。
【问题讨论】:
-
使用
timestamp without time zone而不是timestamp with time zone来记录事件几乎总是错误的做法,除非您只处理来自一个时区的数据,否则会给您带来麻烦。 -
请注意,即使 UTC 也有闰秒,您的 TZ 转换表必须知道这一点。目前 TAI UTC 相差 37 秒。
标签: postgresql timezone timestamp