Skip to main content

3. Two Digit Years (两位数年份)

以下要求旨在解决两位数年份的歧义问题:

要求

o 四位数年份是强制性的

互联网协议必须 (MUST) 在日期中生成四位数年份。

正确示例:

✅ 2002-07-15
✅ 1999-12-31

错误示例:

❌ 02-07-15
❌ 99-12-31

o 两位数年份已弃用

两位数年份的使用已弃用 (Deprecated)。如果收到两位数年份,仅在错误解释不会导致协议或处理失败时才应该 (SHOULD) 接受它(例如,如果仅用于日志记录或跟踪目的)。

o 三位数年份的处理

使用两位数年份的程序可能会将1999年之后的年份表示为三位数。如果程序简单地从年份中减去1900而不检查位数,就会发生这种情况。希望稳健地处理由此类有缺陷的软件生成的日期的程序可以 (MAY) 将1900加到三位数年份上。

示例:

有缺陷的程序输出: 102 (表示2002年)
稳健的解析: 102 + 1900 = 2002年

o 非数字十年位的处理

使用两位数年份的程序可能会将1999年之后的年份表示为 ":0", ":1", ... ":9", ";0", ...。如果程序简单地从年份中减去1900并将十年位加到US-ASCII字符零上,就会发生这种情况。希望稳健地处理由此类有缺陷的软件生成的日期的程序应该 (SHOULD) 检测非数字十年位并进行适当解释。

示例:

有缺陷的程序输出: 
- '0' + 10 = ':' (表示2000年代,ASCII码58)
- '0' + 11 = ';' (表示2010年代,ASCII码59)

稳健的解析应识别这些模式并正确转换

Y2K问题的教训

两位数年份的问题充分证明了为什么在互联网协议中使用的所有日期和时间都必须 (MUST) 完全限定 (Fully Qualified)。


实施建议

生成日期时

✅ 始终使用四位数年份: 2024-12-21
❌ 永远不要使用两位数: 24-12-21

解析日期时

# 稳健的解析示例
def parse_year(year_str):
if len(year_str) == 4:
return int(year_str) # 正确的四位数
elif len(year_str) == 2:
# 已弃用,仅用于向后兼容
year = int(year_str)
if year < 70:
return 2000 + year
else:
return 1900 + year
elif len(year_str) == 3:
# 处理有缺陷的软件
return 1900 + int(year_str)
else:
raise ValueError("Invalid year format")

警告: 虽然本节描述了如何处理两位数年份,但这仅用于向后兼容。新的实现绝对不应该 (MUST NOT) 生成两位数年份。