文档首页> 技术教程> timestamp 与 datetime 的选择与时区坑

timestamp 与 datetime 的选择与时区坑

发布时间:2026-07-20 12:41        更新时间:2026-07-21 08:11
服务器时区一改,应用里的时间凭空差了八小时——这类问题的源头,常常是 timestamp 类型的特性。把两种类型的存储差异弄清楚,选型和排错都不难。 存储差异 datetime 存字面量:写进去是 2026-10-08 15:00:00,读出来还是它,和时区无关,占 8 字节,表示范围到 9999 年。 timestamp 存的是 UTC(协调世界时)时间戳,占 4 字节,读写时按会话时区换算:写入把会话时区的值转成 UTC 存,读出再转回会话时区显示。会话时区一变,同一条记录读出来的"钟表时间"就变了——时区坑的根源就在这个自动换算上。时间的格式化展示交给应用代码去做,数据库只负责老老实实存和取。 2038 话题 4 字节能表示的上限对应 2038 年 1 月,这就是常说的 2038 问题;新版本已经放宽了这一限制,但大量存量系统仍跑在老版本上,约束依然真实存在。业务会活到 2038 年之后的系统,新表选字段时要把这条算进去,长生命周期的数据优先用 datetime。 统一 UTC 的做法 多时区团队或跨国业务的稳妥做法:存储统一 UTC,展示层按用户所在时区渲染。表设计统一用 datetime 存 UTC 值,应用写入前完成转换(主流语言的标准库都支持),会话时区固定: SET time_zone = '+00:00'; 这样任何一台服务器、任何一个会话读到的都是同一个值,时区问题从根上消失。timestamp 的自动换算留给单时区、简单场景使用,用的时候也要把会话时区在连接串里显式定死,不要依赖服务器默认值。 怎么选 需要跨时区自动换算、追求省事,用 timestamp;业务生命周期长、只存不换算、或应用层已经统一存 UTC 的,用 datetime。更重要的是在团队里定一条规范写进建表模板,别让每张表各自拍板。存量老表不必急着动,新增表按规范来,迁移留给有把握的时候再做。