日期距离天数算法,C++实例
关键代码问题分析解决方法完整代码
关键代码
int transformDate(Date
&d
){
const int days
[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
return d
.year
* 365 + days
[d
.month
-1] + d
.day
+ (d
.year
- 1)/4 + ((d
.year
% 4 == 0) && (d
.month
> 2) ? 1 : 0) + (d
.year
? 1 : 0);
}
int Compute(Date
&d1
, Date
&d2
){
return abs(transformDate(d1
) - transformDate(d2
));
}
问题分析
日期距离的计算难点主要是月份天数不一致导致的,特别是2月的天数。
解决方法
1.用一个常量整形数组储存各月1号距离1月1号的天数,这就解决了月份天数不一致导致的问题。(此处先不考虑闰年2月的问题)
const int days
[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
2.降维思想。日期 (2020,10,20) 可以看作是一个三维坐标,计算两点间距离比较麻烦,将此变换成一维坐标 (19) (此处选取(2020.10.1)作为原点)。然后计算两点间距离就简单多了。
d
=
∣
x
1
−
x
2
∣
d=|x_{1} -x_{2}|
d=∣x1−x2∣
坐标变换函数:
int transformDate(Date
&d
){
const int days
[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
return d
.year
* 365 + days
[d
.month
-1] + d
.day
+ (d
.year
- 1)/4 + ((d
.year
% 4 == 0) && (d
.month
> 2) ? 1 : 0) + (d
.year
? 1 : 0);
}
选取坐标原点y
0年1月1日 (y
0,1,1) (y
0为闰年;代码中原点取值y
0=0)待变换坐标 (y,m,d)变换公式: d = (y - y0) * 365 + days[m-1] + d + (y - y0 - 1) / 4 + ((y % 4 == 0) && (m > 2) ? 1 : 0) + (y > y0 ? 1 : 0);
(y - y0) * 365 + days[m-1] + d 这部分是不考虑闰年; (y - y0 - 1) / 4 计算(y0,y)这个区间闰年的数目; ((y % 4 == 0) && (m > 2) ? 1 : 0) 若y是闰年并且m超过了2月再加1天,否则不加; (y > y0 ? 1 : 0) 若y在原点右边加1,左边不加;(因为y0是闰年,故y0后面的年份得加上1天)
完整代码
#include<iostream>
#include<cmath>
using namespace std
;
class Date{
int year
,month
,day
;
friend int Compute(Date
&d1
, Date
&d2
);
friend int transformDate(Date
&d
);
public:
Date(int y
=0, int m
=0, int d
=0){
year
= y
;
month
= m
;
day
= d
;
}
void setDate(){
cout
<<"input a date"<<endl
;
cin
>>year
>>month
>>day
;
}
void show(){
cout
<<year
<<"年"<<month
<<"月"<<day
<<"日"<<endl
;
}
};
int Compute(Date
&d1
, Date
&d2
){
return abs(transformDate(d1
) - transformDate(d2
));
}
int transformDate(Date
&d
){
const int days
[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
return d
.year
* 365 + days
[d
.month
-1] + d
.day
+ (d
.year
- 1)/4 + ((d
.year
% 4 == 0) && (d
.month
> 2) ? 1 : 0) + (d
.year
? 1 : 0);
}
int main()
{
Date d1
,d2
;
d1
.setDate();
d2
.setDate();
d1
.show();
d2
.show();
cout
<<"相差的天数"<<Compute(d1
,d2
)<<endl
;
return 0;
}