You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Postgres中now()与now()::timestamp在CET/CEST时区的结果差异解惑

Postgres中AT TIME ZONE与时间戳类型转换的逻辑解析

首先明确Postgres中两个核心时间戳类型的本质:

  • TIMESTAMPTZ(带时区时间戳):底层存储UTC时间,显示时会根据当前会话时区转换为对应本地时间;
  • TIMESTAMP(无时区时间戳):仅存储字面日期时间值,无时区关联,Postgres无法自动判断它属于哪个时区。

再理清AT TIME ZONE的两种核心行为:

  1. 操作数为TIMESTAMPTZ时:timestamptz_val AT TIME ZONE 'tz' → 将UTC时间转换为tz时区的本地时间,返回**TIMESTAMP类型**;
  2. 操作数为TIMESTAMP时:timestamp_val AT TIME ZONE 'tz' → 将字面时间值视为tz时区的本地时间,转换为对应的UTC时间,返回**TIMESTAMPTZ类型**。

另外,UNION会自动统一列类型:由于你的第一行返回TIMESTAMPTZ,所有其他行的TIMESTAMP结果会被隐式转换为TIMESTAMPTZ——转换规则是把TIMESTAMP的字面值当成**当前会话时区(UTC)**的时间,再转成对应的UTC时间戳。

以下逐个解析你的查询和结果:

行1:SELECT 1, now()

  • now()返回TIMESTAMPTZ,存储的是UTC时间2023-09-10 17:07:10.524389,会话时区为UTC,直接显示为2023-09-10 17:07:10.524389 +00:00。

行2:SELECT 2, now()::timestamp

  • 将TIMESTAMPTZ(UTC17:07)转换为TIMESTAMP,得到字面值2023-09-10 17:07:10.524389;
  • UNION时隐式转为TIMESTAMPTZ:Postgres认为这个字面值是UTC时区的时间,所以最终显示和行1一致。

行3:SELECT 3, now() AT TIME ZONE 'CET'

  • 步骤1:now()(UTC17:07)通过AT TIME ZONE 'CET'转换为CET时区本地时间(CET=UTC+1),得到TIMESTAMP类型的2023-09-10 18:07:10.524389;
  • 步骤2:UNION隐式转为TIMESTAMPTZ:将这个字面值视为UTC时间,所以显示为2023-09-10 18:07:10.524389 +00:00。

行4:SELECT 4, now()::timestamp AT TIME ZONE 'CET'

  • 步骤1:now()::timestamp是TIMESTAMP类型的2023-09-10 17:07:10.524389;
  • 步骤2:AT TIME ZONE 'CET'将这个字面值视为CET时区的本地时间,转换为UTC时间(17:07 - 1小时=16:07),返回TIMESTAMPTZ类型,直接显示为2023-09-10 16:07:10.524389 +00:00。

行3与行4的2小时差原因

行3是UTC→CET本地时间→视为UTC时间戳,行4是UTC字面值→视为CET本地时间→转UTC时间戳,两次转换的时区偏移方向相反(+1和-1),总差值为18:07 - 16:07 = 2小时。

行5:SELECT 5, now() AT TIME ZONE 'CEST'

  • 步骤1:now()(UTC17:07)通过AT TIME ZONE 'CEST'转换为CEST时区本地时间(CEST=UTC+2),得到TIMESTAMP类型的2023-09-10 19:07:10.524389;
  • 步骤2:UNION隐式转为TIMESTAMPTZ,视为UTC时间,显示为2023-09-10 19:07:10.524389 +00:00。

行6:SELECT 6, now()::timestamp AT TIME ZONE 'CEST'

  • 步骤1:now()::timestamp是TIMESTAMP类型的2023-09-10 17:07:10.524389;
  • 步骤2:AT TIME ZONE 'CEST'将这个字面值视为CEST时区的本地时间,转换为UTC时间(17:07 - 2小时=15:07),返回TIMESTAMPTZ类型,显示为2023-09-10 15:07:10.524389 +00:00。

行5与行6的4小时差原因

行5是UTC→CEST本地时间→视为UTC时间戳,行6是UTC字面值→视为CEST本地时间→转UTC时间戳,两次转换的时区偏移方向相反(+2和-2),总差值为19:07 - 15:07 = 4小时。

内容的提问来源于stack exchange,提问作者itinance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:25:09