开发者工具·Unix时间戳转换器
off-by-1000 错误:当日期显示一月 1970 或年份 56000 时
· 为什么它很重要
时间戳 调试 开发人员工作流程
在预期毫秒的地方传递秒(或相反)是最常见的时间戳错误。这篇文章展示了它在各个方向的外观、它在不同语言之间隐藏的位置,以及如何在几秒钟内捕获它。
每个用户于 1 一月 1970 加入 — 泄露错误的屏幕以及完全正确的后端
显示 1 月 1970 附近每个帐户的个人资料页面是一个强烈的规模症状。后端可能已返回正确的纪元秒,而前端代码将它们直接传递给解释毫秒的 Date 构造函数。然后,当前的计数在日历轴上缩小了一千倍。
不要通过添加常量年份或替换日期来修补显示。捕获原始字段、其 API 契约和确切的构造函数调用。 ToolAcre 允许您强制使用两种单位,因此可以在不更改生产数据的情况下测试一个值。与另一个已知事件匹配的读数识别出可能的边界错误。
这两个症状 — 几秒的 API 在一月份 1970 着陆,几毫秒的 API 着陆几万年后
秒被解释为毫秒,接近纪元,因为十亿毫秒只是一个世纪的一小部分。反向错误将万亿毫秒值扩展为万亿秒,通常超出了普通应用范围。这两种失败都保留了数字,同时改变了它们的比例。
发表的十位数与十三位数的文章已经解释了当代视觉启发法及其局限性。本文的重点是诊断和预防:明确的单位选择、独立的事件证据以及生产者的表示满足消费者的契约的界面上的一次转换。
因为两个分支都是确定性的,所以可以用一个夹具重现该症状。这使得单位不匹配比间歇性时钟漂移或区域设置格式化行为更容易证明。
边界通常在哪里 — JavaScript 和 Java 以毫秒为单位,Unix 工具、Python 和大多数数据库以秒为单位,以及它们之间的 JSON 有效负载
这个存储库证明 JavaScript Date 消耗毫秒,而 ToolAcre 在构造日期之前会乘以秒。它不会建立工作簿中指定的每个 Java、Python、shell 或数据库 API 的默认值。必须在使用这些合同的地方进行检查。
JSON 编号不携带单位元数据。将字段命名为 `created_at` 会在服务之间传递歧义;将其命名为 `created_at_s` 或记录 ISO 字符串使合同可供审查。接收适配器应该将其转换一次为其内部表示,而不是在视图之间分散乘法。
在边界定义旁边编写转换,而不是在可重用的显示助手内。适配器知道生产者合约;通用格式化程序应该接收已经标准化的时刻。
单元边界是 API 特定的;这个存储库证明 JavaScript Date 使用毫秒
诸如 `0` 之类的弱固定装置无法检测到该错误,因为零秒和零毫秒都命名了纪元。小的捏造值也可能看起来像可信的 1970 日期。返回消费者期望的相同规模的模拟永远不会出现真正的集成不匹配。
选择一个非零已知时刻并使两种解释明显不同。在边界处断言规范 ISO 结果,而不仅仅是 Date 对象存在。包括毫秒情况和秒情况; ToolAcre 自己的测试正是出于这个原因在每个单元下比较 1,000,000。
当测试无法区分两个尺度时,单元错误就会存在
考虑 `created_at: 1738578000`。强制为秒,则变为 `2025-02-03T10:20:00.000Z`;强制为毫秒,它变成 `1970-01-21T02:56:18.000Z`。已知于 2 月 2025 创建的部署记录解决了歧义,而无需仅依赖数字计数。
在修复适配器时将原始 JSON 保留在已知事件旁边。如果该字段是 `1738578000000`,则毫秒解释将识别同一时刻。尽管转换器可以在应用正确的比例后证明它们的等效性,但决不能在一个模式中互换地接受这两个值。
已知的部署日期是独立证据。如果没有它,选择更合理的输出可能会编码调查人员的期望,而不是确定生产者的意图。
工作示例:在两个显式单位下测试 created_at 值
持久修复从边界开始:解析记录的源单元,仅转换一次并公开键入或明确命名的内部值。架构描述、示例和生成的客户端应保留后缀或日期时间格式。然后,审阅者可以在运行之前发现额外的乘法。
添加具有实际比例和固定 ISO 期望的回归夹具。当生产者有合同时,避免在应用程序代码中自动检测;启发式方法用于调查不确定的遗留数据。 ToolAcre 精确标记其检测到的选择,因此猜测无法伪装成有保证的元数据。
这不包括什么 - 时区错误,这会导致日期按小时而不是按几十年移动
时区错误通常会使显示移动几个小时,并且可能会跨越一个日历日。 1,000 因子的错误会改变数十年或数千年。混合诊断会鼓励围绕已经错误的值进行偏移调整。在检查本地格式之前验证单位。
类似地,错误的纪元原点在秒和毫秒下仍然是无意义的。如果两种解释都不匹配任何已知事件,请停止切换并调查生产者。转换器缩小了假设范围;它并不能证明每个大整数都是 Unix 时间。
如果年份可信,但时间始终错位,则调查区域显示。将这些症状等级分开可以缩短从屏幕截图到根本原因的路径。
要点:错误的单位就是错误的世纪 — 以及 Unix 时间戳转换器的规定单位如何让您立即测试两个读数
错误的单位不是装饰性元数据——它会改变瞬间。将 1970 厚重的屏幕和难以置信的遥远年份视为检查生产者-消费者接缝的信号。价值、单位合同和已知事件构成了比表面上合理的日期更强有力的三部分证据。
使用转换器比较显式读数,然后在名称、类型和测试中对所选标度进行编码。我们的目标不是教软件更聪明地猜测。它是从为用户创建日期的路径中删除猜测。
然后,代码审查可以在每个边界提出一个精确的问题:什么单元进入,什么单元离开?这比识别特定数量的数字更可靠。