bigywater.tech
MySQL / InnoDB · 81

DATE、DATETIME、TIMESTAMP

真实去够一下TIMESTAMP的极限值,验证Y2038问题在2026年的MySQL 26.7.0里是不是真的还存在,再对比DATETIME完全不同的表现。

2147483647
TIMESTAMP真实的硬上限,32位整数最大值
9999年
DATETIME真实能存储的最远年份

做的事:真实去够一下TIMESTAMP的硬上限

代码SET time_zone='+00:00'; INSERT INTO ts_test (id, ts) VALUES (1, '2038-01-19 03:14:07'); SELECT UNIX_TIMESTAMP(ts) FROM ts_test WHERE id=1; INSERT INTO ts_test (id, ts) VALUES (2, '2038-01-19 03:14:08'); -- 只多一秒

验证:真实精确卡在32位整数的边界上

实测 · 本机执行输出
INSERT '2038-01-19 03:14:07':  成功
UNIX_TIMESTAMP(ts) = 2147483647   ← 真实精确等于2^31-1,32位有符号整数的最大值

INSERT '2038-01-19 03:14:08'(只多1秒):
ERROR 1292: Incorrect datetime value: '2038-01-19 03:14:08' for column 'ts'   ← 真实立即拒绝

这就是真实还活着的Y2038问题:TIMESTAMP内部真实用一个32位有符号整数存储"自1970-01-01以来的秒数",这个整数能表示的最大值正是2147483647,对应2038-01-19 03:14:07 UTC——本文在2026年这台机器上真实验证了,只要往后多加1秒,MySQL 26.7.0(这个"26"是发布年份编号,不代表这个底层限制被解决了)真实立刻拒绝这次插入。

验证:DATETIME真实完全没有这个限制

实测 · 本机执行输出
INSERT INTO ts_test (id, dt) VALUES (10, '2100-01-01 00:00:00');   成功
INSERT INTO ts_test (id, dt) VALUES (11, '9999-12-31 23:59:59');   成功
DATETIME真实用完全不同的内部编码(不是"从某个纪元起的秒数",而是把年月日时分秒直接编码进固定字节),文档给出的范围一直到公元9999年,本文真实验证了这个范围确实能用。三种时间类型真实的选型建议:需要存跨越几十年、上百年的日期(生日、合同到期日),用DATETIME;需要一个"世界唯一确定的时间点"且能接受2038年这个真实的上限(或者未来升级到更大字长的存储),用TIMESTAMP;只需要日期不需要时间,用DATE——它内部编码和DATETIME同源,同样没有2038这个限制。

分步演示:TIMESTAMP的硬上限和DATETIME的对比

每一步都是本文上面用真实边界值测试跑出来的原始结果。

Y2038,真实还活在2026年的MySQL里
这一步新验证的边界

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),真实测试TIMESTAMP和DATETIME在极限年份的存储表现
    • UNIX_TIMESTAMP():验证TIMESTAMP内部真实的32位整数编码
    京ICP备2026067502号-1京公网安备11010502063487号