PostgreSQL timestamp 列里存了什么?
一句话先讲清:在 PostgreSQL 里,
timestamp
/timestamptz
列其实都只是存了一串「距离 1970-01-01 00:00:00 UTC 的秒数」——数据库用这串数字帮你记住时间,再按你的需求转换成“人能读懂”的格式。
为什么会困惑?
很多人第一次用 PostgreSQL 都会碰到这些问题:
timestamp
和timestamptz
有什么区别?- 明明插入了 “2025-07-29 10:00”,查询时怎么变成了别的时间?
- 我把时间戳保存下来,前端却显示不一致……
这篇文章用 小白能理解的语言 + 类比 + 例子,拆开说清楚到底存了什么,同时顺带告诉你如何用 Go Tools 的时间转换小工具 一键验证,避免「时区坑」。
一、两种「时间罐子」:没有标签 vs 带标签
数据类型 | 官方名字 | 内部怎么存 | 查询时会发生什么 |
---|---|---|---|
timestamp | timestamp without time zone | 纯数字(微秒数) | 不自动做时区转换,直接输出你插入的数字对应的日期时间 |
timestamptz | timestamp 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,足够你穿越。
timestamp
和timestamptz
存的数字 完全一样,只是解释方式不同。
想直观看到这串数字?
打开 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 | 查询时才换算 |
四、常见坑 & 解决思路
-
不同客户端看到的时间不一致
- 原因:用了
timestamptz
,各客户端TimeZone
设置不同。 - 解决:要么统一用
timestamp
+ 约定时区,要么强制所有连接SET TimeZone = 'UTC';
。
- 原因:用了
-
想保存「本地时间」却用错类型
- 如果业务只关心“当地日历时间”(例如商场营业日期),用
timestamp
。 - 如果要跨时区展示、计算间隔,用
timestamptz
+ 统一存 UTC。
- 如果业务只关心“当地日历时间”(例如商场营业日期),用
-
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。祝你写库无坑,查库开心!