postgresql - 区分夏令时转换期间的时间

标签 postgresql logging time

我正在查看来自英国时区的一些输出,该时区跨越了夏令时转换(对于任何不知道的人,在 10 月的最后一个星期日的早上,重复凌晨 1 点以减去一个小时,同样在3 月的最后一个星期日,它向前移动 1 小时)。输出显示时间似乎倒退的事件 - 显然这是小时重置的结果,但是没有任何时间偏移列表,确定正确时间的唯一合乎逻辑的方法是查看它们的顺序。我知道 Postgres 在 UTC 内部存储带有时区的时间戳,但是当指定时区时,偏移量被省略,例如

select
    '2019-10-27 00:30:00 UTC'::timestamptz at time zone 'Europe/London' time1,
    '2019-10-27 01:30:00 UTC'::timestamptz at time zone 'Europe/London' time2,
    '2020-03-29 00:30:00 UTC'::timestamptz at time zone 'Europe/London' time3,
    '2020-03-29 01:30:00 UTC'::timestamptz at time zone 'Europe/London' time4;

您可以在下面看到 10 月的转换将在 00:30 和 01:30 期间给出完全相同的时间,但它不显示时区偏移,因此无法分辨两者之间的区别。

        time1        |        time2        |        time3        |        time4        
---------------------+---------------------+---------------------+---------------------
 2019-10-27 01:30:00 | 2019-10-27 01:30:00 | 2020-03-29 00:30:00 | 2020-03-29 02:30:00

这显然不仅仅是一个只影响 Postgres 的问题,而且输出到一个不使用偏移量的日志文件,所以没有明确的方法来追溯时间。我很幸运,订单确实有所不同,但假设在这样的 2 小时内只有一个事件,那么将来处理这个(合理不规则)问题的最佳做法是什么?是否可以仅在这些期间显示偏移量或是否有其他解决方案?

最佳答案

解决方案很简单:不记录本地时间戳。

要么记录时区信息和时间戳,要么在记录之前将它们转换为 UTC:

SET timezone = 'Europe/London';

select                         
    '2019-10-27 00:30:00 UTC'::timestamptz time1,
    '2019-10-27 01:30:00 UTC'::timestamptz time2,
    '2020-03-29 00:30:00 UTC'::timestamptz time3,
    '2020-03-29 01:30:00 UTC'::timestamptz time4;

         time1          |         time2          |         time3          |         time4          
------------------------+------------------------+------------------------+------------------------
 2019-10-27 01:30:00+01 | 2019-10-27 01:30:00+00 | 2020-03-29 00:30:00+00 | 2020-03-29 02:30:00+01
(1 row)

select                         
    '2019-10-27 00:30:00 UTC'::timestamptz at time zone 'UTC' time1,
    '2019-10-27 01:30:00 UTC'::timestamptz at time zone 'UTC' time2,
    '2020-03-29 00:30:00 UTC'::timestamptz at time zone 'UTC' time3,
    '2020-03-29 01:30:00 UTC'::timestamptz at time zone 'UTC' time4;

        time1        |        time2        |        time3        |        time4        
---------------------+---------------------+---------------------+---------------------
 2019-10-27 00:30:00 | 2019-10-27 01:30:00 | 2020-03-29 00:30:00 | 2020-03-29 01:30:00
(1 row)

关于postgresql - 区分夏令时转换期间的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58590495/

相关文章:

c - adjtime(x) 调整时间很慢

iphone - 如何在iPhone上获取精确到1秒的系统时间

Postgresql:检测哪个外键触发了 "on before delete"触发器

mysql - 为地址更改+定价创建正确的数据库表结构

MySql 搜索不同行之间的共享值

c++ - 文件输出覆盖第一行 - C++

ruby-on-rails - rails dynamic where sql 查询

sql - 评论(一次编写)存储网络信息的数据库设计

logging - 在Gitlab CI/CD中集成日志文件

c - Pebble C 将 char 转换为时间以在 double difftime(time_t end, time_t begin) 中使用