Zeller日期公式
计算原理
选定一个日期,并且知道它是周几,作为参考点,计算相差的天数。
$ D_1 $ 表示从参考点到参考点年末的天数。
$ D_2 $ 表示从参考点所在年份到当前年份的所有天数。
$ D_3 $ 表示从当前年份第一天到当前年份当前日期的天数。
如果参考点选在 12 月 31 日那么就不需要计算 $ D_1 $ 了,因为 $ D_1 = 0 $ 。
$ D $ 模除 7 然后需要加上参考点周几的偏移量,如果参考点为周日就不需要偏移量了。公元元年前一年的12月31日刚好是周日,刚好满足所有要求。
所以 $ D\mod7 $ 的余数就是周几。
计算 $ D_2 $
也就是相差的年数为 $ y-1 $ ,乘以天数 $ 365 $ ,然后加上闰年的个数。(闰年:能被 $ 4 $ 整除但是不能被 $ 100 $ 整除,能被 $ 400 $ 整除)
计算 $ D_3 $
不考虑闰年的话,每年中 2 月份天数最少,为 28 天。因此,可以把月份的天数看做 28 + 增量的形式。
月份 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
天数 | 31 | 28 | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 |
增量 | 3 | 0 | 3 | 2 | 3 | 2 | 3 | 3 | 2 | 3 | 2 | 3 |
前缀和(m月之前) | 0 | 3 | 3 | 6 | 8 | 11 | 13 | 16 | 19 | 21 | 24 | 26 |
因此
这是以公元前1年的 12 月 31 日为起点的。 $ D-1 $ 为从1,1,1开始的天数。
故
1 | // weekday=(id+1)%7;{Sun=0,Mon=1,...} getId(1, 1, 1) = 0 |