项目背景
在计算机科学与数学领域中,有一类非常有意思、也非常'优雅'的算法:心算友好型算法。它们不依赖复杂计算,却能通过规律和结构,快速得到结果。
Doomsday Algorithm(末日算法),正是其中最著名的代表之一。
该算法由传奇计算机科学家 John Horton Conway 提出,用于快速计算任意日期是星期几。末日算法的特点是规则清晰、可解释性强,既适合人脑心算,也非常适合程序实现,是算法思维、数学建模、时间系统理解的绝佳案例。
在工程实践中,虽然我们可以直接调用标准库,但自实现有助于理解历法、闰年、模运算,也是面试中经常考察的「日期算法原理」。
本文将使用 Go 语言,完整实现一套可教学、可运行、可验证的 Doomsday 末日算法。
项目需求
功能性需求
- 输入任意合法日期(年、月、日)
- 输出该日期对应的星期
- 支持公历(Gregorian Calendar)
- 正确处理闰年规则
- 提供完整示例可直接运行
非功能性需求
- 不依赖 time 包的 Weekday 计算
- 算法步骤清晰、易于讲解
- 适合博客、课堂、面试讲解
- 所有代码放在单一代码块中
技术原理
什么是 Doomsday(末日)
在 Doomsday 算法中,**Doomsday(末日)**指的是:某一年中,一组'固定日期'都落在同一个星期几。
例如(非闰年):
- 4 月 4 日
- 6 月 6 日
- 8 月 8 日
- 10 月 10 日
- 12 月 12 日
它们在同一年中,星期几是完全一致的。
年锚点(Century Anchor Day)
每个世纪都有一个固定的'锚点星期',例如:
- 1900–1999:星期三
- 2000–2099:星期二
这是算法中非常关键的一步。
闰年规则说明
公历闰年规则:
- 能被 400 整除 → 闰年
- 能被 100 整除但不能被 400 整除 → 平年
- 能被 4 整除但不能被 100 整除 → 闰年
实现思路
算法总体流程
- 计算世纪锚点星期
- 计算当年 Doomsday 星期
- 找到该月的 Doomsday 日期
- 根据日期差值推算目标星期
月份 Doomsday 对照表
| 月份 | 平年 | 闰年 |
|---|---|---|
| 1 | 1 月 3 日 | 1 月 4 日 |
| 2 | 2 月 28 日 | 2 月 29 日 |
| 3 | 3 月 14 日 | 3 月 14 日 |
| 4 | 4 月 4 日 | 4 月 4 日 |
| 5 | 5 月 9 日 |

