我很惊讶地在 postgres 中select date_trunc('day','2021-02-16 20:00+04'::timestamptz);
返回了2021-02-17 00:00:00+08
。
就像我们从 16 世纪前进到了 17 世纪。
我想检查我的理解并找到解释这一点的资料来源(最好是官方的)。
会议已set timezone = 'Asia/Singapore'; --utc+8
我的理解
截断之前发生了 2 次转换:
- 20:00+04 变成 16:00+00,存储为 8 位整数(纪元时间微秒),postgres 使用它来表示物理时间中的时刻(与https://errorprone.info/docs/time中提到的民用时间相反)
- 运行时
date_trunc
,16:00+00 变为第二天 00:00+08,因为date_trunc
以当地时间(会话时区)解释
我通过将输入改为 来测试该假设2021-02-16 20:00+05
,其输出为2021-02-16 00:00:00+08
。(没有天数增量)。
我猜这是因为第一次变换又往回回了 1 个小时至 15:00+00,所以第二次变换只达到 16 日晚上 11 点而不是 17 日凌晨 12 点?
我找不到任何文档提及这种双重解释行为。最接近的是以下:
当输入值是带时区的时间戳类型时,截断将根据特定时区执行;例如,截断为白天将产生该时区午夜的值。默认情况下,截断将根据当前 TimeZone 设置进行,但可以提供可选的 time_zone 参数来指定不同的时区。
https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC