在网上无意间看到的dalao分享,真的很眼前一亮
int countdays(int y, int m, int d)
{
if (m < 3){
y--;
m+=12;
}
return 365*y+(y>>2)-y/100+y/400+(153*m-457)/5+d-306;//nb的式子背过就好
}
dalao的推演过程也分享在这里吧
函数功能 计算出该年该天距离0001-1-1(公元1年1月1日)的天数
算法思路: 1,先找出每个月天数的规律
把1月和2月当成上一年的13月和14月
月份:03-04-05-06-07;08-09-10-11-12;13-14;
天数:31-30-31-30-31;31-30-31-30-31;31-30(28)
为了凸显规律,5个月,5个月一组
规律就是:1-0-1-0-1(重复)
2,找到m个月之前有多少天的公式(以3月为第一个月)
由此规律就可以知道在m月(以3月为第一个月)之前有多有多少天
月份:03-04-05-06-07;08-09-10-11-12;13-14;
天数: 0- 1- 1- 2- 2; 3- 4- 4- 5- 5; 6- 7(28)(7用不到)
所以有此表达式:(3*m-7)/5
加上每个月30天后的gl
月份:03-04-05-06- 07; 08- 09- 10- 11- 12;13-14;
天数: 0-31-61-92-122;153-184-214-245-275;306-337(28)
(因为求得是每个月之前的天数,正好2月在最后一天,所以这个数据可以舍弃,直接加上day即可(day<=28))
所以有此表达式:( 153 * m - 457 ) / 5,求得m月之前有多有多少天
如:m=3,之前只有0天
m=4,之前有31天
…
但是这是以3月为第一个月的每个月之前的天数
当月数为3月之前,总天数不可能为负数,所以当月数为3月之前时,要将其转化为13,14月
但是这样子在三月之前的天数都时300多天,相当于向前一年借了有年,所以年数要减少一年
所以得出天数的规律:365 * y + ( 153 * m - 457 ) / 5 - 306 + d
3,解决闰年每年多一天的问题
四年一闰,百年不闰,四百年再闰
所以每四年天数就要多一天:y >> 2(相当于y / 4(取整))
但是每100年就不闰,所以百年时的天数不会相加,所以要减回去
同理四百年再闰,还得加上这些年有多少个400年,补上2月多有的一天
所以核心结果就是右边的公式:365 * y+(y>>2)-y/100+y/400+(153 * m-457)/5+d-306