本文主要是介绍基姆拉尔森 (Kim larsen) 星期计算公式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
W = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7
其中m / d / y分别代表月 (month)、日 (day)、年 (year);1月和2月对应的m是13和14,同时y相应-1
W = 1 ~ 0 分别代表着星期一 ~ 星期日;
简单的验证一下:0年1月1日(0 - 周日),1年1月1日(1 - 周一),2020年3月24日(2 - 周二)
推导(参考https://bbs.csdn.net/topics/70277519)
整个推导的核心思想,是得到y年m月1日是星期几,然后推演出y年m月中,d和W的关系!
0年1月1日是周日,则最开始一周的天数和星期数有如下对应关系:
1 - 周日(W = 0), 2 - 周一(W = 1), ......,7 - 周六(W = 6)
7天一个周期,因此对于0年的1月,有
W = (d - 1)% 7 ····················································································(1)
以一年365天计算,365 = 7 * 52 + 1,也就意味着每过一年,第一天的星期数都会增长1,因此对于y年的1月,有
W = (d - 1 + y)% 7 ···············································································(2)
闰年有366天,因此需要将y - 1年中的所有闰年考虑进来(参考上图,y年是否闰年不影响y年1月的星期数),因此,对y年的1月,有
W = (d - 1 + y + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400)% 7 ···························(3)
类似不同年之间星期数的推算,可以对不同月份的星期数做推算,m月1号 - (m - 1)月1号 = (m - 1)月天数,如果该天数是7的倍数,则W和d的推演关系不变;否则向后推延 (m - 1)月天数 % 7。以y为非闰年为例,有
m月 | 天数 | 天数 % 7 | m月1日较1月1日的推延 |
1 | 31 | 3 | 0 |
2 | 28 | 0 | 3 |
3 | 31 | 3 | 3 |
4 | 30 | 2 | 6 |
5 | 31 | 3 | 8 -> 1 |
6 | 30 | 2 | 4 |
7 | 31 | 3 | 6 |
8 | 31 | 3 | 9 -> 2 |
9 | 30 | 2 | 5 |
10 | 31 | 3 | 7 -> 0 |
11 | 30 | 2 | 3 |
12 | 31 | 3 | 5 |
偏差e = {0,3,3,6,1,4,6,2,5,0,3,5} (y非闰年)
W = (d - 1 + y + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + e [m - 1])% 7 ··········(4)
但此时,对于y是闰年的情况,又会得到新的一组e;此时W的公式取决于y是否为闰年。为了避免分情况讨论的繁琐,一个机智的做法是将N年的1月和2月并入N-1年,作为13月和14月。在此基础上,我们重新推导:
============================ 我是分割线 ============================
0年3月1日是周三,则最开始一周的天数和星期数有如下对应关系:
1 - 周三(W = 3), 2 - 周四(W = 4), ......,7 - 周二(W = 2)
7天一个周期,因此对于0年的3月,有
W = (d + 2)% 7 ····················································································(1)
以一年365天计算,365 = 7 * 52 + 1,也就意味着每过一年,第一天的星期数都会增长1,因此对于y年的3月,有
W = (d + 2 + y)% 7 ··············································································(2)
闰年有366天,因此需要将y年中的所有闰年考虑进来(参考上图,y年是否闰年影响y年3月的星期数),因此,对y年的3月,有
W = (d + 2 + y + y / 4 - y / 100 + y / 400)% 7 ···························(3)
类似不同年之间星期数的推算,可以对不同月份的星期数做推算,m月1号 - (m - 1)月1号 = (m - 1)月天数,如果该天数是7的倍数,则W和d的推演关系不变;否则向后推延 (m - 1)月天数 % 7。
m月 | 天数 | 天数 % 7 | m月1日较3月1日的推延 |
3 | 31 | 3 | 0 |
4 | 30 | 2 | 3 |
5 | 31 | 3 | 5 |
6 | 30 | 2 | 8 -> 1 |
7 | 31 | 3 | 3 |
8 | 31 | 3 | 6 |
9 | 30 | 2 | 9 -> 2 |
10 | 31 | 3 | 4 |
11 | 30 | 2 | 7 -> 0 |
12 | 31 | 3 | 2 |
13 | 31 | 3 | 5 |
14 | 28 / 29 | 0 / 1 | 8 -> 1 |
可以发现,y年是否为闰年,偏差均为e = {0,3,5,1,3,6,2,4,0,2,5,1} 。注意,e的最后两个值对应y+1年的1月和2月,这里暂不作讨论。对于y年3~12月,均有
W = (d + 2 + y + y / 4 - y / 100 + y / 400 + e[m - 3])% 7 ····································(4)
令x = m - 3,则e[x] = [2 * (x + 3) + 3 * (x + 4) / 5 - 1] % 7,因此有 e[m - 3] = 2 * m + 3 * (m + 1) / 5 - 1,因此,对于y年3~12月,有
W = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400)% 7 ········(5)
而对于y年的1~2月,将其作为y - 1年的13~14月来求解,则会发现y年是否是闰年,只会影响y - 1年14月的天数,对y - 1年13月和14月的星期数求解并无影响。
令x = m - 3,对于m=13和14的情况,仍有e[x] = [2 * (x + 3) + 3 * (x + 4) / 5 - 1] % 7,因此有 e[m - 3] = 2 * m + 3 * (m + 1) / 5 - 1。所以以下求解式对所有情况都通用:)
W = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7
这篇关于基姆拉尔森 (Kim larsen) 星期计算公式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!