世界末日规则(Doomsday Rule)是用来心算任意一天星期几的,由约翰·何顿·康 发明。
约翰·何顿·康威(英语:John Horton Conway,1937年12月26日-2020年4月11日),生于英国利物浦,数学家,活跃于有限群的研究、趣味数学、纽结理论、数论、组合博弈论和编码学等范畴。
康威年少时就对数学很有强烈的兴趣:四岁时,其母发现他背诵二的次方;十一岁时,升读中学的面试,被问及他成长后想干什么,他回答想在剑桥当数学家。后来康威果然于剑桥大学修读数学,后为普林斯顿大学的教授。于 2020 年 4 月11日因COVID-19去世。
最早知道康威教授应该就是 leetcode 289 Game of Life 生命游戏了,感兴趣的同学可以复习一下[旺柴]
言归正传,下边介绍具体的方法。
算今年的日期
特殊日期
首先记几个特殊的日子:
| 1 月 3 号 | 2 月 28 号 | 4 月 4 号 | 5 月 9 号 | 6 月 6 号 | 7 月 11 号 |
|---|---|---|---|---|---|
| 8 月 8 号 | 9 月 5 号 | 10 月 10 号 | 11 月 7 号 | 12 月 12 号 |
然后看一下今年的日历,会发现他们都是星期日!
接下来的问题是怎么速记这些日期:
首先大部分月份都是 X 月 X 日,也就是月份和日是一样的,我们只需记住四个特殊的日子:
7 月 11 日和 11 月 7 日,可以想一下 7 eleven 便利店。

5 月 9 号和 9 月5 号,这里只需要记住一个词语,朝九晚五,本来是用来形容工作时间的,9点上班,5 点下班,但现在看起来有些困难了。

然后会随闰年变化的,非闰年是 1 月 3 号和 2 月的最后一天 28 号,闰年的话都推后一天变为 1 月 4 号和 2 月的最后一天 29 号。
3 月没有锚定日,可以根据 2 月最后一天的日期来推算。
数学规律
可以对照日历看一下:

如果我们知道了 12 月 12 号是星期日,那么这个月的任意一天是星期几我们就都可以很快算出来了。
首先 12 号的 7 天后和 7 天前都还是星期日。12 号的 3 天后和 4 天前都是星期三。
可以通用出三条规则:
某一天的
x天前的星期几和7 - x天后的星期几是完全一样的。某一天的
x天后的星期几和7 - x天前的星期几是完全一样的。某一天加上
x天或者减去x天,对x进行任意次的加7和减7,星期几不会发生变化。
举个例子,我们要算 31 号星期几,以 12 号为锚点。 31 - 12 = 19,也就是 12 号的 19 天后是星期几,19 - 7 - 7 = 5,也就是 12 号的 5 天后是星期几,很简单,星期五。
如果我们要算 1 号星期几,以 12 号为锚点。 12 - 1 = 11,也就是 12 号的 11 天前是星期几,11 - 7 = 4,也就是 12 号的 4 天前是星期几,星期日往前数 4 天不好算,应用第一条规则,我们可以算 7 - 4 = 3 天后星期几,12 号三天后是星期三,所以 1 号就是星期三。
实战一下
确认今年的锚定日,也就是星期日,那些特殊日期都是星期日。
| 1 月 3 号 | 2 月 28 号 | 4 月 4 号 | 5 月 9 号 | 6 月 6 号 | 7 月 11 号 |
|---|---|---|---|---|---|
| 8 月 8 号 | 9 月 5 号 | 10 月 10 号 | 11 月 7 号 | 12 月 12 号 |
此时就可以对着你的女朋友说,你知道你生日(10 月 4 日)那天星期几吗?
不知道
(锚定日是 10 月 10 号,10 - 4 = 6 ,星期日的 6 天前,也就是 1 天后),星期一!我还能说出今年任意一天的星期几你信吗?
8 月 8 号呢?
(刚好是锚定日,开心,然后可以脱口而出),星期日!
平安夜呢?
(12 月 24 号星期几?锚定日是 12 号,24 - 12 = 12 ,12 - 7 = 5 ,星期日的 5 天后),星期五!
666
(以上均为臆想,我女朋友最后回答是这有什么用呢,不如翻日历,哈哈,祝大家成功,开阔其他场景展示这个超能力)
前后 100 年的星期几
其实我们只需知道那一年的锚定日是星期几,并且知道那一年是不是闰年来确定我们的特殊日,后边的计算就和上边的方法一样了。
我们来记一个特殊的锚定日,2000 年的锚定日是星期二,然后记住三条规则:
- 每过一个平年,锚定日星期数加
1,每过一个闰年,锚定日的星期数加2。 - 每过
12年,锚定日的星期数就加1。比如2000年是星期二,2012年就是星期三,2024年就是星期四。 - 每相隔
28年,只要相隔的两年在一个世纪内,或者跨过2000年,那么它们的锚定日都在一个星期。比如1972年与2028都是星期二。
比如计算自己出生时候 1996-01-29 是星期几?先算 1996 的锚定日是星期几。
2000 年是星期二,根据规则 1,往前数 4 年,因为 2000 年是闰年,所以从 1999 年到 2000 年星期加了二,所以 1999 年是星期日,1998 年是星期六,1997 年是星期五,1996 年是星期四。
1996 年是闰年,特殊日期就是 1 月 4 号,29 - 4 等于 25,25 - 3 * 7 = 4,星期四的 4 天后是星期一!
所以 1996-01-29 就是星期一。
再算一下 2049-10-01 是星期几?
应用规则 3,2028 年锚定日是星期二。
应用规则 2,2028 + 12 = 2040 年锚定日是星期三,2040 + 12 = 2052 年是星期四。
因为 2052 年是闰年,所以从 2051 年到 2052 年星期加了二,所以 2051 年是星期二,2050 年是星期一,2049 年锚定日就是星期日。
10 月 10 日是特殊日,10 - 1 = 9,9 - 7 = 2 ,星期日的两天前就是星期五!
所以 2049-10-01 是星期五!
任意年的星期几
上边我们记了 2000 年的锚定日是星期二,根据下边的规则我们可以推出任意百年前和百年后的锚定日是星期几。
每过 100 年的锚定日星期数按下面规律变化:星期二,星期日,星期五,星期三,星期二,星期日,星期五,星期三……每 4 年循环一次 。
所以 2100年的锚定日是星期日,1900 年是星期三。
知道了任意世纪的一个锚定日,再通过上边 前后 100 年的星期几 的规则,我们就可以推出任意年的星期几了。
我们来算一下 8888 年 8 月 8 日是星期几吧。
(8888 - 2000) / 100 = 68 余 88 ,过了 68 个百年,每四个百年一个周期,68 / 4 = 17,整除了,所以 2000 + 6800 = 8800 年的锚定日和 2000 年一样也是星期二。
((8888 - 8800)) / 28 = 3 余 4,8800 + 28 * 3 = 8884,每相隔 28 年锚定日相同,所以 8884 的锚定日和 8800 年相同是星期二。
8885 年是星期三,8886 年是星期四,8887 年是星期五,8888 年是闰年,所以星期五加 2 天后就是星期日。
所以 8888 年的锚定日也就是星期日!
8 月 8 号刚好是特殊日期,所以 8888 年 8 月 8 号是星期日!无图无真相,看下截图:

一起挑战
摘抄一段 机器之心 对约翰·康威博士的介绍。
「约翰·康威博士坐在他的电脑面前准备登录。但在计算机允许他工作之前,它快速弹出了
10个随机选出的过去和未来的日期,比如3/15/2005或4/29/1803。康威博士必须心算每一个日期的星期数才能让电脑允许他打开文件开始工作。这是他为自己准备的游戏。」在
1972年左右发明了这个「末日游戏」之后,康威给自己设定了一个目标,快速连续计算10个日期的速度每隔五年都要加快一倍。落脚普林斯顿大学也没有让他偏离自己的轨迹。「为什么我想很快?因为这很了不起。」他说,「这是个很不错的聚会玩乐。我不知道这是否曾让我结识任何妹子,但这种事可能能偶然让人结识到合适的妹子——一种特定类型的妹子。」那时,他计算完所有全部
10个日期的时间是15.92秒,差不多每个1.5秒。他没有脱离自己的速度翻倍目标,而且他告诉那位记者他是世界上最快的人。
然后这几天抽空写了小程序 「快速星期几」,大家可以感受下,哈哈。

特别鸣谢我家领导对 UI 的详细建议,大家感受下前后的差别,哈哈。
