system.currenttimemillis() 不会发生溢出,因其返回的 long 类型最大可表示至公元 292278994 年,远超人类文明及软件生命周期;实际风险在于 int 截断、负差值或逻辑错误,而非时间戳本身溢出。

System.currentTimeMillis() 返回的是从 1970-01-01 00:00:00 UTC(Unix 纪元)开始的毫秒数,类型为 long。Java 的 long 是 64 位有符号整数,取值范围是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。
这意味着它能表示的最大时间戳约为公元 292,278,994 年,远超人类当前和可预见的使用场景。所以——在正常业务逻辑中,System.currentTimeMillis() 不会发生溢出,无需主动“处理”溢出问题。
为什么不用担心溢出
当前时间(比如 2025 年)对应的时间戳约是 1.7×10¹² 毫秒,而 Long.MAX_VALUE 是约 9.2×10¹⁸ 毫秒。换算成年份:
- 最大可表示时间 ≈ 292278994 年 12 月(UTC)
- 距离现在还有超过 2.9 亿年
- 远超太阳寿命(约 50 亿年后红巨星化),也远超任何软件生命周期
真正需要注意的“溢出”误区
开发者常误以为“溢出”发生在以下场景,其实本质是计算或类型转换错误,而非 currentTimeMillis() 本身溢出:
- 用 int 存储时间戳:int 最大值约 21 亿毫秒(≈ 24.8 天),2025 年就早超了——这是类型截断,不是 long 溢出
-
计算差值时未考虑符号:比如
(end - start)若 start > end(如系统时间被手动回拨、NTP 调整),可能得到负值,但这属于逻辑异常,不是溢出 - 与过期时间比较时逻辑写错:例如把“大于过期时间”写成“小于”,导致误判失效,和溢出无关
安全使用建议
确保时间相关逻辑健壮,重点防范实际风险:
- 始终用
long类型接收和存储currentTimeMillis()结果 - 避免隐式类型转换,尤其警惕
int、short、byte参与时间运算 - 计算时间差时,用
Math.abs(end - start)或明确判断先后顺序,防止负值引发逻辑错误 - 涉及定时、缓存过期等场景,优先使用
java.timeAPI(如Instant.now().toEpochMilli()),语义更清晰且类型安全
极端情况下的理论提醒(仅作知识补充)
如果真运行到公元 292278994 年之后——
- Java 规范未定义该行为,但按二进制补码规则,
Long.MAX_VALUE + 1会变成Long.MIN_VALUE(即时间跳回公元前 292278994 年左右) - 这属于整数回绕(wrap-around),不是异常,也不会抛出错误
- 届时更该关心 JVM 是否还存在、硬件是否支持、时区定义是否有效……而不是写修复代码 ?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











