Skip to main content

3. Two Digit Years (两位数年)

以下要求解决了两位数年引起的歧义问题:

要求

o 四位数年份是强制性的

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

正确示例:

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

错误示例:

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

o 两位数年已被弃用

两位数年的使用已被弃用。如果收到两位数年份, 只有在误解不会导致协议或处理失败的情况下才应该接受 (例如, 如果仅用于日志记录或跟踪目的)。

o 处理三位数年

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

示例:

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

o 处理非数字的十位数字

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

示例:

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

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

Y2K 的教训

两位数年的问题充分说明了为什么互联网协议中使用的所有日期和时间必须是完全限定的。


实现建议

生成日期时

✅ 始终使用四位数年份: 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")

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