简体中文

开发者工具·Unix时间戳转换器

年 2038 问题:当 32 位 time_t 溢出时会发生什么

· 背景

时间戳 unix 时间 调试

有符号的 32 位计数器在连续时间线旁边达到其上限
原始 ToolAcre 矢量图

在 19 一月 2038 的 03:14:07 UTC 时间,带符号的 32 位第二个计数器回绕到 1901。这篇文章解释了算法,其中 32 位时间仍然隐藏,以及如何识别将受到影响的系统。

一个比听起来更接近的日期 — 抵押贷款、证书和固件已经计算出超过 2038 的日期

日期为 2038 的限制在计算超过该点的到期日、计划或保留期限时都会影响代码。因此,故障可能会比时钟日期早几年出现。该存储库不记录抵押、证书或固件产品,因此这些示例不会作为观察案例呈现。

实际的审计问题是是否有任何边界将 Unix 秒存储在带符号的 32 位整数中。成功格式化未来日期的现代浏览器并没有说明下游字段较窄。跟踪序列化和持久性,而不仅仅是用户界面。

在今天的测试中搜索未来日期的计算,而不是等待生产时钟。固定的边界装置将遥远的日历问题变成了即时的、可重复的检查。

未来日期计算可以在 2038 之前暴露 32 位限制,但此处未证明指定行业

有符号的 32 位整数的最大值为 2³1−1 或 2,147,483,647。测试确定纪元后的许多秒为 `2038-01-19T03:14:07.000Z`。再数学一秒应该是 03:14:08,ToolAcre 会显示它,因为 JavaScript 数字和日期可以携带该值。

换行为负值需要外部有符号 32 位操作; `fromEpoch` 不执行一项操作。经常被引用的 12 月 1901 结果可以通过补码换行推导出来,但声称每个受影响的系统都换行而不是拒绝、饱和或损坏将超出证据范围。测试实际边界。

如果外部转换包含补码算术,请检查结果存储的位和解码的负值。不要仅根据意外的历史日期来推断换行。

验证准确的上限时刻;换行行为取决于外部整数运算

搜索保存纪元秒的 32 位签名字段的模式、协议定义和二进制布局。名为 INTEGER 的 SQL 列不足以在所有引擎中提供足够的证据,并且嵌入式平台不会自动受到影响。确定每个路径的宽度、符号、单位和转换代码。

在审核中包括文件和缓存记录。加宽的内存类型仍然可以写入旧的窄格式,而宽数据库可以接收截断的客户端值。在最大值和超出的值处创建固定装置,然后检查字节或持久值,而不仅仅是检查函数是否返回成功。

通过检查实际模式和格式找到签名的 32 位纪元字段

概念上的修复是一种表示,其范围包括所需的日期,通常是更宽的有符号计数或适当的时间类型。工作簿的内核、libc 和格式迁移叙述位于这些源文件之外。每个系统都有自己的兼容性和部署工作。

扩大每个边界作为协调的合同变更。在没有线域的情况下更新存储,或者在没有现有数据的情况下更新存储,会留下狭窄的链接。在必要时添加版本控制并显式测试老读者。纪元定义本身不需要改变;容器确实如此。

迁移规划必须包括回滚和混合版本行为。在任何持久日期到达日历边界之前,生成宽值的新写入器可能会破坏旧读取器。

扩大表示是核心修复;内核和格式迁移是特定于系统的

将2,147,483,647转换为秒,得到`2038-01-19T03:14:07.000Z`;转换 2,147,483,648 以获得 `2038-01-19T03:14:08.000Z`。平滑的一秒步骤证明 ToolAcre 路径在该值处没有 32 位悬崖。

现在强制使用与毫秒相同的数字。它们落在 1970 一月,因为这些值在零后大约二十五天变成。这种比较可以防止单元错误被错误标记为 2038 问题。字段宽度和比例是独立的尺寸。

此比较还说明了为什么转换器是诊断性的而不是易受攻击的:显式的单位选择决定了比例,而浏览器的更广泛的表示形式包含这两个值。

工作示例:转换器跨越边界,因为 JavaScript 日期未签名 32 位秒

存储库还将 4,294,967,295 秒测试为 `2106-02-07T06:28:15.000Z`,即最大无符号 32 位计数。它不测试 GPS 周翻转或指定带符号的 64 位毫秒悬崖,因此这些命名主题被省略而不是概括。

边界分析应遵循所使用的确切类型。从有符号切换到无符号会向一个方向延伸,但会删除负日期,但仍会创建上边缘。更广泛的签名表示通常保留两个方向,具体取决于消费者的日期范围。

每个悬崖都需要从宽度、符号和单位中得出自己的推导。将不相关的翻转分组在“2038”下会掩盖哪个二进制字段实际需要更改。

无符号 32 位边界;其他命名的悬崖位于储存库证据之外

转换器无法审核源代码、二进制文件、数据库模式或已部署的设备。它显示了候选编号的含义并提供了用于测试的具体装置。静态搜索、型式检验、序列化测试和迁移演练必须确定产品是否安全。

不要关闭审核,因为浏览器正确呈现 2038。这仅验证此浏览器路径。端到端地遵循值,尤其是通过可能发生隐式缩小的语言绑定和旧格式。

在该跟踪中包含依赖项和供应商接口。应用程序源可能使用宽类型,而本机库或设备协议无形中缩小了相同的值。

要点:纪元没问题,整数宽度是问题 — 以及 Unix 时间戳转换器如何让您检查 UTC 和本地时间中的任何边界值

年份 2038 问题是整数宽度边界,而不是 Unix 纪元算术中的缺陷。 ToolAcre 两侧的成功转换使这种分离变得可见。仅当外部系统的其中一个表示无法携带下一个计数时,外部系统才会失败。

使用 2,147,483,647 和 2,147,483,648 作为相邻测试向量,验证精确的持久性,并记录单位和符号。每个边界的证据都比所谓易受攻击的技术的通用清单更有价值。

相邻向量应该跨越真实的序列化路径,而不仅仅是内存中的计算。这就是名义上加宽的应用程序可以显示剩余的狭窄接缝的地方。