我查看了英国时区的一些输出,该时区跨越了夏令时转换(对于任何不知情的人,在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的问题,而且输出到一个不使用偏移量的日志文件中,因此没有明确的方法来追溯时间我很幸运,订单确实说明了区别,但假设在这两个小时内只有一个事件,那么在未来处理这个(相当不规则的)问题的最佳做法是什么?是否只能在这些期间显示偏移量,或者是否有其他解决方案?
最佳答案
解决方法很简单:不要记录本地时间戳。
记录时区信息和时间戳,或在记录之前将其转换为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)