缘起

看到有记忆大师秒出日期-->星期的转换,研究了一下记忆规律,总结如下。

原理

公元元年 0001年1月1日:星期一
计算日期距离元年第一天的前一天的天数,对7取模

计算xxxx年yy月zz日是星期几

计算公式

w = xxxx年yy月zz日距离公元元年前一天的天数 % 7
w = ((年份 - 1) * 365 + 闰年数 + 该日期距同一年1月1日的天数) % 7
w = ((年份 - 1) * 365 + 闰年数 + 该日期同月第一天距离同一年1月1日的天数 + 该日期距离当月1日的天数) % 7
w = ((年份 - 1) + 闰年数 + 该日期同月第一天距离同一年1月1日的天数 % 7 + 该日期距离当月1日的天数) % 7

0表示星期日,1~6表示星期一~星期六

由于最终结果需要模7,所以在实际计算天数的过程中,不需要真的计算,只需要取模7的余数即可。

含义 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
M(每个月的天数) 31 28 31 30 31 30 31 31 30 31 30 31
M % 7 3 0 3 2 3 2 3 3 2 3 2 3
yy月1日距离xxxx年1月1日天数 % 7 0 3 3 6 1 4 6 2 5 0 3 5

如果当年是闰年:

含义 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
M(每个月的天数) 31 29 31 30 31 30 31 31 30 31 30 31
M % 7 3 1 3 2 3 2 3 3 2 3 2 3
yy月1日距离xxxx年1月1日天数 % 7 0 3 4 0 2 5 0 3 6 1 4 6

把上述公式分成三个部分:

w = (年份代码y + 月份代码m + 日期代码d) % 7
y = (年份 - 1) + floor((年份 - 1) / 4)
m = 当月1日距离当年1月1日的天数 % 7
d = 当月日期 - 1

以2000年1月1日为例:
w = ((2000 - 1) * 365 + floor((2000 - 1) / 4)  + 0 + (1 - 1)) % 7 = 6
所以2000年1月1日是星期六

以千禧年为计算基础计算20xx年yy月zz日是星期几

千禧年 2000年1月1日:星期六,该日期的前一天是星期五。

千禧年相比公元元年,本身是闰年,多1天。为了让结果便于记忆,将起始计算日期调整为1999年12月31日,星期五,则上述公式调整如下:

w = (年份代码y + 月份代码m + 日期代码d) % 7
y = xx + xx / 4
m = (yy月1日距离xx年1月1日的天数 + 5) % 7  : 闰年
m = (yy月1日距离xx年1月1日的天数 + 6) % 7  : 非闰年,非闰年比闰年多1个完整闰年,所以多1天
d = zz

备注:

  • 此处d比通用公式的d多1,因为计算是从2000年的前一天开始的。所有的变量都放在了m,方便记忆。

以千禧年首日代替公元元年,由于2000年是闰年,1月1日是星期六,因此m计算方法从6开始,如下

含义 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
M(每个月的天数) 31 28 31 30 31 30 31 31 30 31 30 31
M % 7 3 0 3 2 3 2 3 3 2 3 2 3
(yy月1日距离xx年1月1日天数 + 6) % 7 6 2 2 5 0 3 5 1 4 6 2 4

如果xx年是闰年,由于在计算y的时候已经多包含了1天,所以首月要少一天,m的计算方法从5开始,如下

含义 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
M(每个月的天数) 31 29 31 30 31 30 31 31 30 31 30 31
M % 7 3 1 3 2 3 2 3 3 2 3 2 3
(yy月1日距离xx年1月1日天数 + 5) % 7 5 1 2 5 0 3 5 1 4 6 2 4

如何快速记忆2000年之后的星期代码

  • 非闰年的月份代码: 622503 514624
  • 闰年的月份代码:   512503 514624
    这个数字非常好记,闰年是51,费闰年是62开头,其他都一样。

案例

2019.3.25
(19 + 4 + 2 + 25) % 7 = 1,所以答案是星期一

jiyi-rili