1. AT TIME ZONE 子句的双向语义,timestamptz 转 timestamp、timestamp 转 timestamptz?
请说明 PostgreSQL 中 AT TIME ZONE 子句的双向语义,即 timestamptz 转 timestamp 与 timestamp 转 timestamptz 分别如何工作?
- 双向转换的语义差异
- timestamptz(时间点)转 timestamp(本地时间)
- timestamp 转 timestamptz(按会话时区解读)
PostgreSQL 的 AT TIME ZONE 有双向语义:timestamptz AT TIME ZONE zone 返回 timestamp,把该时间点转换到指定时区的本地时间(去掉时区标记);timestamp AT TIME ZONE zone 返回 timestamptz,把该"无时区"字面时间按指定时区解读为某个时间点。二者方向相反:前者是"时间点→本地时间",后者是"本地时间→时间点"。结果类型恰好互换。
关键要区分"时间点"(timestamptz,绝对时刻)与"墙钟时间"(timestamp,无时刻)。AT TIME ZONE 是两者之间唯一的转换桥梁,方向决定结果类型。
SELECT '2020-01-01 12:00:00+00'::timestamptz AT TIME ZONE 'Asia/Shanghai'; -- 20:00:00
SELECT '2020-01-01 12:00:00'::timestamp AT TIME ZONE 'Asia/Shanghai'; -- 04:00:00+00