在 PostgreSQL 里,TIMESTAMPTIMESTAMPTZTIMESTAMP WITH TIME ZONE)都能存储日期和时间,但差别在时区处理


1️⃣ TIMESTAMP [WITHOUT TIME ZONE]

  • 只存储日期+时间,不包含时区信息。

  • PostgreSQL 不会自动做时区转换。

  • 输入什么就存什么,取出时也是原样。

示例:

-- 建表 CREATE TABLE t1 ( ts TIMESTAMP ); -- 插入数据 INSERT INTO t1 VALUES ('2025-09-26 12:00:00'); INSERT INTO t1 VALUES ('2025-09-26 12:00:00+08'); -- 时区会被忽略

查询结果(假设系统时区是 UTC+8):

ts --------------------- 2025-09-26 12:00:00 2025-09-26 12:00:00

👉 无论写没写时区,最后都按字面值存储。


2️⃣ TIMESTAMP WITH TIME ZONE (TIMESTAMPTZ)

  • 存储的是一个绝对时间点(内部统一保存为 UTC)。

  • 插入时会自动转换成 UTC 存储,查询时再根据当前会话时区显示。

示例:

-- 建表 CREATE TABLE t2 ( ts TIMESTAMPTZ ); -- 插入数据(系统时区假设是 UTC+8) INSERT INTO t2 VALUES ('2025-09-26 12:00:00'); -- 按本地时区解读(UTC+8) INSERT INTO t2 VALUES ('2025-09-26 12:00:00+00'); -- 明确指定 UTC INSERT INTO t2 VALUES ('2025-09-26 12:00:00-05'); -- 明确指定美国东部时间

查询结果(会话时区为 UTC+8):

ts ------------------------ 2025-09-26 12:00:00+08 2025-09-26 20:00:00+08 2025-09-27 01:00:00+08

👉 可以看到:

  • 第一条:解释为北京时间 2025-09-26 12:00(存成 UTC 04:00)。

  • 第二条:存的 UTC 2025-09-26 12:00,显示成北京时间 20:00

  • 第三条:存的 UTC 2025-09-26 17:00,显示成北京时间 次日 01:00


3️⃣ 实际开发建议

  • 业务无关时区(例如生日、只表示“某天”):用 TIMESTAMP

  • 需要绝对时间点(例如登录时间、订单创建时间、日志时间):用 TIMESTAMPTZ


总结

  • TIMESTAMP:存的是“日历上的时间”,不带时区。

  • TIMESTAMPTZ:存的是“绝对时间点”,内部转成 UTC,查询时根据会话时区转换。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部