摘要

  • RFC 868 通过 TCP 或 UDP 的 37 号端口返回一个从 1900 年 1 月 1 日起算的 32 位秒数。
  • 2036 年边界从第一版规范起就已写明;回绕的精确时刻来自字段宽度的计算,规范本身只写了年份。
  • NTP 后来把单次时间读数扩展为时钟同步,并处理数值属于哪个时代的问题。

让机器拿到可比较的数字

1983 年,有些系统没有日历时钟,即使有时钟也可能发生人为或机器误差。RFC 868 给出的办法很克制:简短地询问几个彼此独立的站点,再用回复核对本机对时间的判断。这是一种共同的数据表示,不等于一套完整的同步算法。

服务器监听 37 号端口。TCP 客户端建立连接后,服务器返回一个 32 位二进制数并关闭;UDP 客户端发送空数据报,服务器回送带有这个数的数据报。数值表示自格林尼治时间 1900 年 1 月 1 日午夜以来经过的秒数。如果服务器无法确定本地时间,规范要求它拒绝或关闭 TCP 连接而不提供数字,或对 UDP 请求不作答。

规范没有规定怎样抵消网络时延、筛选可信服务器、认证回复或调整客户端的本地时钟。数字易于机器读取,仍不代表它已被证明准确。

面向人的另一种时间服务

同月的 RFC 867 Daytime 在 13 号端口发送 ASCII 日期时间,服务于调试和测量。它建议使用可打印字符,却不固定一种文本格式,并将机器使用的时间需求指向 RFC 868。两份规范谈的是不同表示与用途,并没有证明两个服务端具有相同的时钟质量。

1900 年起点早于常用的 Unix 时间起点 1970 年。RFC 868 自己列出换算值:1970 年 1 月 1 日 GMT 零点对应 2,208,988,800。固定参考点使不同系统的数字可以比较,但双方必须共享相同的单位和起算方式。

这个紧凑字段的期限也被写在规范里:“基准将适用到 2036 年”。无符号 32 位计数器从 1900 年起达到 2³² 秒的时刻是 2036 年 2 月 7 日 GMT 06:28:16。这是依据字段宽度和基准推算出的时刻,RFC 868 只标出年份。下一秒超出字段范围,数值重新从零开始。若没有其他日期上下文,回绕后的数字可能与第一轮中的数字相同。

NTP 不只回传一个样本

1985 年的 RFC 958 说明,Network Time Protocol(NTP)从 RFC 868 和 ICMP Timestamp 演进而来,适合取代两者。NTP 要同步的是一组网络时钟,涉及分布式客户端和服务器;这比返回某个服务器的一次读数更进一步。

NTP 延续 1900 年参考纪元,但要解释多轮计数。RFC 5905 介绍了时间戳中的 32 位秒数字段,以及 2036 年从时代 0 转入时代 1。报文还包括小数部分,而完整时间时代仍需要上下文。规范描述了如何用大致的当前时间解释回绕附近的值。

这不是某种格式后来变得永不过期的故事。RFC 868 用固定短值简化查询,也预先标出了有效边界。NTP 接过了同步和时代解释这两个更大的问题。互联网把 1900 年写进报文时,字段的边界也一并写进了标准:一个数字本身无法永远说明自己属于哪段时间。

来源与证据边界

主要来源是 1983 年 5 月的 RFC 868《Time Protocol》。RFC 867 提供同期 ASCII 服务对照,RFC 958 记录 NTP 自述的沿革,RFC 5905 说明后来的时代处理。这些资料不能证明 RFC 868 的实际部署数量、时间精度、全网迁移或 2036 年会发生故障。

RFC 2626 也提到了 2036 年回绕;它印出的具体分钟数与上述计算不符,因此本文只采用其对年份边界的提醒,不采用那个时刻(RFC 2626)。Heng Lu 的 Note 65 仅用于提出“实现如何延续书面规则”的编辑问题,是阅读视角而非历史证据(Note 65)。