PostgreSQL timestamp 列里存了什么?

一句话先讲清:在 PostgreSQL 里,timestamp/timestamptz 列其实都只是存了一串「距离 1970-01-01 00:00:00 UTC 的秒数」——数据库用这串数字帮你记住时间,再按你的需求转换成“人能读懂”的格式。


为什么会困惑?

很多人第一次用 PostgreSQL 都会碰到这些问题:

  • timestamptimestamptz 有什么区别?
  • 明明插入了 “2025-07-29 10:00”,查询时怎么变成了别的时间?
  • 我把时间戳保存下来,前端却显示不一致……

这篇文章用 小白能理解的语言 + 类比 + 例子,拆开说清楚到底存了什么,同时顺带告诉你如何用 Go Tools 的时间转换小工具 一键验证,避免「时区坑」。


一、两种「时间罐子」:没有标签 vs 带标签

数据类型官方名字内部怎么存查询时会发生什么
timestamptimestamp without time zone纯数字(微秒数)不自动做时区转换,直接输出你插入的数字对应的日期时间
timestamptztimestamp with time zone同样是微秒数自动把这串数字按 session 的 TimeZone 参数转换后再输出

类比

  • timestamp 像是一罐没有贴标签的罐头。你知道里面是桃子(=具体时间),可是不知道产地(=时区)。
  • timestamptz 就是一罐贴好了「产地:UTC+8」标签的罐头。拿到哪儿(客户端),大家都能看懂产地,再决定要不要换算。

二、内部真的只是「一长串数字」

在 PostgreSQL 16 中:

2000-01-01 00:00:00 UTC  →  0
2000-01-01 00:00:01 UTC  →  1 000 000
  • 单位是 微秒(百万分之一秒)。
  • 64 位整数可精确到 4713 BC ~ 294276 AD,足够你穿越。
  • timestamptimestamptz 存的数字 完全一样,只是解释方式不同。

想直观看到这串数字?
打开 Go Tools → 时间戳转换器,输入日期即可查看对应的微秒或毫秒值,反之亦可。


三、简单例子:一秒看懂差异

-- 设置会话时区为 'Asia/Shanghai'
SET TimeZone = 'Asia/Shanghai';

CREATE TABLE demo (
  created_ts   timestamp,
  created_tz   timestamptz
);

INSERT INTO demo VALUES
  ('2025-07-29 10:00', '2025-07-29 10:00');  -- 插入同一行
查询列结果解释
SELECT created_ts FROM demo;2025-07-29 10:00:00原样输出
SELECT created_tz FROM demo;2025-07-29 10:00:00+08先记数字,再贴 +08 标签
SET TimeZone = 'UTC'; SELECT created_tz FROM demo;2025-07-29 02:00:00+00查询时才换算

四、常见坑 & 解决思路

  1. 不同客户端看到的时间不一致

    • 原因:用了 timestamptz,各客户端 TimeZone 设置不同。
    • 解决:要么统一用 timestamp + 约定时区,要么强制所有连接 SET TimeZone = 'UTC';
  2. 想保存「本地时间」却用错类型

    • 如果业务只关心“当地日历时间”(例如商场营业日期),用 timestamp
    • 如果要跨时区展示、计算间隔,用 timestamptz + 统一存 UTC。
  3. JSON/API 传输变乱

    • 建议后端统一把 timestamptz 转成 ISO 8601 字符串(含 Z 或时区偏移),前端再本地格式化。

Go Tools → 时区转换器 一键校验:
输入 “2025-07-29 10:00 Asia/Shanghai”,立刻得出对应 UTC、纽约、伦敦时间,肉眼查对,放心上线。


五、选择哪种?一图速记

仅本地日历→ timestamp
跨时区交互→ timestamptz
  • 写财务报表、排课表timestamp(关心日期,不关心偏移)
  • 记录日志、订单、跨国会议timestamptz(关心绝对时间)

六、用 Go Tools 帮你「秒级验证」

场景推荐工具用法
手动检查 SQL 输出的 epoch 数时间戳转换器粘贴 1690622400 → 看人类时间
快速看两个时区差多少时区转换器输入 “10:00 Asia/Shanghai” → 自动列出全球主要城市
大批量格式优化JSON 格式化工具把接口返回贴进来,一键美化 + 检查时间字段

不用后端、纯前端运行——所有转换都在浏览器内完成,数据不会上传服务器,安全又快捷。


小结

  • PostgreSQL timestamp/timestamptz 都存微秒,区别在 是否自动贴时区标签
  • 选错类型会导致显示混乱、计算出错;
  • 借助 Go Tools 的时间戳 & 时区工具,三步内就能验证并排除常见坑。

下一次当你再次问自己 “pg timestamp 列里到底存了什么?”,想起这篇小抄,再点开 Go Tools 一验证——问题瞬间解决,开发效率直接 +1。祝你写库无坑,查库开心!