UNIX 时间戳总结

2038年问题,又称Unix千年臭虫或Y2K38错误,是因Unix时间戳采用32位整数表示而产生的错误。当时间戳超过2038年1月19日03:14:07UTC,时间值将变为负数,导致日期回滚至1901年12月13日。本文探讨了该问题的原因、影响及可能的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UNIX 时间戳

unix_timestamp

延伸阅读:Y2K38 错误

2038年问题又叫Unix千年臭虫或Y2K38错误。在时间值以带符号的32位整数来存储或计算的数据存储情况下,这个错误就有可能引发问题。

可以用Unix带符号的32位整数时间格式来表示的最大时间是 2038年1月19日03:14:07UTC(2038-01-19T03:14:07Z),这是自 1970-01-01T00:00:00Z 之后过了 2147483647 秒,值的边界如下:

时间时间戳二进制字面量
1970-01-01T00:00:00Z000000000 00000000 00000000 00000000
2038-01-19T03:14:07Z2^31-1, 214748364701111111 11111111 11111111 11111111

测试代码:

// 0
long a = 0;
// 2^31-1, 2147483647
long b = Integer.MAX_VALUE;

// 1970-01-01T00:00:00.000Z
Instant.ofEpochSecond(a).atZone(ZoneOffset.of("-00:00")).toLocalDateTime()
// 2038-01-19T03:14:07.000Z
Instant.ofEpochSecond(b).atZone(ZoneOffset.of("-00:00")).toLocalDateTime()

过了最大时间后,由于整数溢出,时间值将作为负数来存储,系统会将日期读为1901年12月13日,而不是2038年1月19日。

用简单的语言来说,Unix机器最终将会耗尽存储空间来列举秒数。所以,到那一天,使用标准时间库的C程序会开始出现日期问题。你可以在维基百科上详细阅读更多的相关内容(https://en.wikipedia.org/wiki/Year_2038_problem)。

下面这个动画显示了2038年错误将如何重置日期:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIYPNCEB-1612353563376)(https://qidawu.github.io/img/distribute/Y2K38.GIF)]

资料来源:维基百科

目前,2038年错误没有什么通行的解决方案。如果对用于存储时间值的time_t数据类型的定义进行更改,依赖带符号的32位time_t整数性质的应用程序就会出现一些代码兼容性问题。假设time_t的类型被更改为不带符号的32位整数,那将加大最新的时间限制。但是,这会对由负整数表示的1970年之前的日期造成混乱。

使用64位架构的操作系统和程序使用64位time_t整数。使用带符号的64位值可以将日期延长至今后的2920亿年。

已有人提出了许多建议,包括以带符号的64位整数来存储自某个时间点(1970年1月1日或2000年1月1日)以来的毫秒/微秒,以获得至少30万年的时间范围。其他建议包括用新的库重新编译程序,等等。这方面的工作正在开展之中;据专家们声称,2038年问题解决起来应该不难。

参考

UNIX时间 - 维基百科

https://time.is/UTC

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dylan、

耕码不易,白嫖可耻

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值