<前提>
<1>
先不考虑闰年的情况下,每年365天,365%7=1,也就是说第二年的某一天(月日)是第一年的那一天(月日)的下一天,这样可以得出公式1(不考虑闰年,只考虑一月的情况)
DayOfWeek = (d-1 + y) % 7 公式(1)
<2>
再考虑闰年的情况,我们知道闰年的计算公式:1. 普通闰年:每4年一次;2.世纪闰年:每400年一次。 因此当年的之前的闰年数目:
NumOfLeapYear = (y-1)/4 - (y-1)/100 + (y-1)/400
这样我们可以推导出公式2(考虑了闰年的一月的情况)
DayOfWeek = (d-1 + y + (y-1)/4 - (y-1)/100 + (y-1)/400) % 7 公式(2)
再来考虑非一月份的情况,如果每个月恰巧是28天的话,所有的月份都可以按照一月的day进行计算,也就是说后面的月份还得考虑一个偏移量。如下表所示(暂不考虑闰年的情况)
| 月份 | 天数 | 偏差(相对于28天) | 当月累计偏差(相对于28天) | 当月偏移量(累计偏差模7) |
|---|---|---|---|---|
| 1 | 31 | 3 | 0 | 0 |
| 2 | 28 | 0 | 3 | 3 |
| 3 | 31 | 3 | 3 | 3 |
| 4 | 30 | 2 | 6 | 6 |
| 5 | 31 | 3 | 8 | 1 |
| 6 | 30 | 2 | 11 | 4 |
| 7 | 31 | 3 | 13 | 6 |
| 8 | 31 | 3 | 16 | 2 |
| 9 | 30 | 2 | 19 | 5 |
| 10 | 31 | 3 | 21 | 0 |
| 11 | 30 | 2 | 24 | 3 |
| 12 | 31 | 3 | 26 | 5 |
// golang// Offset of the monthOM = [...]int{0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}
DayOfWeek = (d-1 + y + (y-1)/4 - (y-1)/100 + (y-1)/400 + OM[m-1]) % 7 公式(3)
// 0年3月1日是星期三DayOfWeek = (d + 2 + y) % 7 公式(1)'// 因为3月开始作为元月,之前有多少闰年的计算也就和当年有关DayOfWeek = (d + 2 + y + y/4 - y/100 + y/400) % 7 公式(2)'// 偏移查找表DayOfWeek = (d + 2 + y + y/4 - y/100 + y/400 + NewOM[m-3]) % 7 公式(3)'
重新计算查找表
| 月份 | 天数 | 偏差 | 当月累计偏差 | 当月偏移量 |
|---|---|---|---|---|
| 3 | 31 | 3 | 0 | 0 |
| 4 | 30 | 2 | 3 | 3 |
| 5 | 31 | 3 | 5 | 5 |
| 6 | 30 | 2 | 8 | 1 |
| 7 | 31 | 3 | 10 | 3 |
| 8 | 31 | 3 | 13 | 6 |
| 9 | 30 | 2 | 16 | 2 |
| 10 | 31 | 3 | 18 | 4 |
| 11 | 30 | 2 | 21 | 0 |
| 12 | 31 | 3 | 23 | 2 |
| 13(1) | 31 | 3 | 26 | 5 |
| 14(2) | 28/29 | 0 | 29 | 1 |
NewOM = [...]int{0, 3, 5, 1, 3, 6, 2, 4, 0, 2, 5, 1}
神(无)奇(聊)的数学家推导出
令m-3=x,NewOM[x]满足表达式 [2 * (x + 3) + 3 * (x + 4) / 5 - 1] % 7m取值范围是[3, 14]因此NewOM[m-3] = [2*m + 3*(m+1)/5 -1] % 7
这样可以得到最后的一个唯一公式
DayOfWeek = (d + 1 + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7 公式(3)''
当然这个公式中的m取址范围是[3, 14],当计算1、2月时,就把它看成前一年的13、14月份。
严谨的同学肯定会说,对于0年的1、2月份上面的公式是否通用?代个值进去看看就知道啦!例如:0年1月1日
d = 1, m = 13, y = -1=> DayOfWeek = (1 + 1 + 2*13 + 3*(13+1)/5 -1) % 7 = 0
<后续>
/** 蔡勒公式* 1582.10.4之后 w = (y + y/4 + c/4 - 2*c + (26*(m+1))/10 + d - 1) % 7* 1582.10.4及之前 w = (y + y/4 + c/4 -2*c + (13*(m+1))/5 + d + 2) % 7;*/
文章转载自工程师站台,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




