来看公式:
int CaculateWeekDay(int y,int m, int d) { if(m==1||m==2) { m+=12; y--; } int iWeek=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; return iWeek; }
这个公式叫基姆拉尔森公式。
该公式是从公元0年1月1日开始推导的
刚看挺复杂,我逐一分析:
iWeek= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) %7
1.
(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) %7
d表示天数,天数对7取模,这个好理解
2.
(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) %7
不考虑瑞年,则每天为 365 天。由于365是7的52倍多1天,所有加上y
3.
(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) %7
如果考虑闰年,由于闰年比平年多一天,
y/4-y/100+y/400
该公式表示y(包括y)年前共有多少天闰年
4.
(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) %7
由于每个月份天数都不一样,便于公式映射,这里把1月和2月看成13月份和14月份
有人会问为什么非得把1,2月份当作13 ,14月份呐,为什么不是1,2,3或其他的呐?
因为只有2月份的天数是随着闰年和平年变化的,如果是三月份随着平年和闰年变化的,那就把1,2,3移动到其后面成为13,14,15月份
要问为什么?
看下表:
月
误差 累计 模7
3 3 0 0
4 2 3 3
5 3 5 5
6 2 8 1
7 3 10 3
8 3 13 6
9 2 16 2
10 3 18 4
11 2 21 0
12 3 23 2
13 3 26 5
14 - 29 1
发现没有,二月份的误差是不用计算的,所以就解决了二月份天数变化与整年的变化的一致性。
至于这个公式:
2*m+3*(m+1)/5
其实就是用公式对模7的一个映射,你试试,所有的月份大小输进去都可以映射到模7上
你也可以用一个数组存储模7,然后用下标调用
不过还是公式比较好用一点