现在的位置: 首页 > 综合 > 正文

求两个日期之间相差天数的一个算法。

2017年12月01日 ⁄ 综合 ⁄ 共 2047字 ⁄ 字号 评论关闭

今天写到一个类需要用到求两个日期之间相差的天数。我只好写一个时间累。之前写过一个但是用了许多许多的判断。代码页找不到了,需要重写。这次重写我希望找到简单的办法。按照计算机计时的思想,我可以计算两个日期到某一个指定日期的天数,然后在求差。网上找了一下算法,终于在yaoweijq的这篇文字里面找到了算法。大家可以去他的这个文章看一看实现。点击打开链接,下面是我类中重载减法运算符,用于计算两个日期之间的相隔天数。

int CDate::operator-(const CDate d)const{
	int days;
	int nm  = (_Month + 9) % 12;     //
	int ny = _Year - nm / 10;
	int nd = 365 * ny + ny / 4 - ny / 100 + ny / 400 + (nm * 306 + 5) / 10 + (_Day - 1);

	int nm1 = (d._Month + 9) % 12;
	int ny1 = d._Year - nm1 / 10;
	int nd1 = 365 * ny1 + ny1 / 4 - ny1 / 100 + ny1 / 400 + (nm1 * 365 + 5) / 10 + (d._Day - 1);

	days = nd - nd1;

	return days;
}
其中的nd就是当前日期到0年3月1日之间的天数。

相信看过前面链接里的文章的同学有一部分已经明白了。没有明白页没关系我来讲述一下,今天有点忙早上这个类还没写完就被同学叫去写单片机程序了。吃饭的时候把不明白的东西思考了一下,基本明白了。这个算法是分别计算两个日期至0年3月1日的天数,然后求差。至于为什么选择3月1日。我也不知道。

废话不在说了,下面分析一下。

int nm  = (_Month + 9) % 12;     
这一句用于检测当月是否在3月1日之前,因为我们知道是否为闰年是有2月来决定决定的,如果在2月以前我们就不用考虑本年,这个道理应该明白吧。
仔细看1月2月两月 求得的结果是10,11 。3月至12月nm为0~9。
看到这里我想你很迷糊为什么这么做。那我们来看第二句吧。
int ny = _Year - nm / 10; 
这一句,ny 用于存储年,nm/10 这一步 1,2月两个月得到的结果为1 其他月份是0。所以这里在3月1日之前的我们把年减去一。因为我们是从3月1日开始计算的,当前不满一年。
int nd = 365 * ny + ny / 4 - ny / 100 + ny / 400 + (nm * 306 + 5) / 10 + (_Day - 1);
这一句相当犀利,不得不佩服算法的作者。
365*ny我们先把每一年当做平年。+ny/4  四年一闰年。还有后面-ny/100 ,100年不闰年。+ny/400 四百年闰年。这个是大家都应该明白的吧。看(nm * 306 + 5) / 10  这一个,思考了整个吃饭时间。
为什么要是306呢。365-31-28=306 (是一年的天数减去一月和二月的天数,为什么要这么做?因为我们这里元旦是3月1号。因为前面我们计算了到0年3月1日之间的天数现在我们需要做的就是计算当前日期到本年的3月1号的天数)(nm * 306 + 5) / 10  为什么这样。我不妨把它带入各个月份来看(别忘了这个int nm  = (_Month + 9) % 12;
   
 )
我们看一下每个月对应得nm是多少看一下(nm*306+5)/10 是多少 
    nm                          (nm*306+5)/10

1月-----nm =10 ---------- 306  = 265+31
2月-----nm =11 ---------- 336  =  306+30
3月-----nm =0
  ----------  0
4月-----nm =1
 -----------  31=0+31
5月-----nm =2 ------------  61=31+30
6月-----nm =3
 -----------  92= 61+31
7月-----nm =4 ------------122=  92+30
8月-----nm =5 ------------153 = 122+31
9月-----nm =6 ------------ 184 = 153+31
10月---nm =7 ------------214 = 184+30
11月---nm =8 ------------ 245 = 214+31
12月---nm =9 -----------  275  =  245+30


这里我们惊讶的发现用这样的方法居然可以算出 每个月份的1号到3月1日之间的天数。如果你自己算一遍的时候你会发现,这里的+5 起到了至关重要的作用,也不知道为什么每当该月是大月的时候这个5就可以帮我们来导致进位,比如9月 ,9月的nm是6(6*306)=1836 加上5以后就是 1841了  这样除以10以后就是 184了。
不知道这种巧合是有缘由的还是,这个方法提出者的精心推导。
最后 加上当前的 日期 ,+(_Day-1)   减一为什么你自己想  7月7日距离7月1日  是不是 7-1?
ok 时间仓促,就写到这里,如有问题希望指正。如有不懂,再看一遍。
以下是我的测试。常规的日期没有问题。

我们换一个极端的。


也没有问题,初步证明这个方法还是比较可靠地。
如果发现有问题,请告诉我。谢谢。









抱歉!评论已关闭.