有人问我“计算两日期相差的天数”的程序,状态很差,晕晕的写的很差。回家睡醒重写了一个,用了两种方式。顺便开辟博客记录相关知识和小代码。
实现了两种方式:
- 日期++或日期--,直到两日期相同,效率较差,代码较多。
- 将日期转换为时间戳,直接计算结果,效率高,代码少。
为了传参方便,自定义了时间结构体,代码如下:
#include <iostream>
#include <time.h>
#include <string.h>
using namespace std;
struct MyDate
{
unsigned int y;
unsigned int m;
unsigned int d;
};
unsigned int g_dayNumOfMon[13];
bool InitDayNumOfMon(unsigned int *a);
bool IsR(unsigned int y);
bool AddOneDay(MyDate &d);
int CampDate(const MyDate &d1, const MyDate &d2);
bool SwapDate(MyDate &d1, MyDate &d2);
size_t GenTimestamp(const MyDate &d);
unsigned int GetDayNumOfMon(const MyDate &d);
int CalDayNumBetween2Date(MyDate d1, MyDate d2);
int CalDayNumBetween2Date2(const MyDate &d1, const MyDate &d2);
int main()
{
InitDayNumOfMon(g_dayNumOfMon);
MyDate d1, d2, d3;
d1.y = 2011;
d1.m = 9;
d1.d = 17;
d2.y = 2016;
d2.m = 6;
d2.d = 18;
d3.y = 2016;
d3.m = 6;
d3.d = 19;
int num11 = CalDayNumBetween2Date(d1, d2); // 自增 || 自减方式
int num12 = CalDayNumBetween2Date(d2, d3);
int num1_21 = CalDayNumBetween2Date(d2, d1);
int num2_12 = CalDayNumBetween2Date2(d1, d2); //高效方式
int num2_21 = CalDayNumBetween2Date2(d2, d1);
cout<<"diff days:"<<num11<<endl;
cout<<"diff days:"<<num12<<endl;
cout<<"diff days121:"<<num1_21<<endl;
cout<<"diff days12:"<<num2_12<<endl;
cout<<"diff days21:"<<num2_21<<endl;
return 0;
}
bool InitDayNumOfMon(unsigned int *a)
{
for(int i = 1; i <= 12; ++i)
{
if(4 == i || 6 == i || 9 == i || 11 == i)
a[i] = 30;
else if(2 == i)
a[i] = 28;
else
a[i] = 31;
}
return true;
}
bool IsR(unsigned int y)
{
if((0 == y % 4 && 0 != y % 100) || (0 == y % 400))
return true;
else
return false;
}
unsigned int GetDayNumOfMon(const MyDate &d)
{
if(2 != d.m)
return g_dayNumOfMon[d.m];
if(IsR(d.y))
return 29;
return 28;
}
bool AddOneDay(MyDate &d)
{
if(d.d < GetDayNumOfMon(d))
{
++d.d;
return true;
}
d.d = 1;
if(12 <= d.m)
{
d.m = 1;
++d.y;
}
else
++d.m;
return true;
}
int CampDate(const MyDate &d1, const MyDate &d2)
{
int id1 = d1.y * 10000 + d1.m * 100 + d1.d;
int id2 = d2.y * 10000 + d2.m * 100 + d2.d;
if(id1 > id2)
return 1;
else if(id1 < id2)
return -1;
else
return 0;
}
bool SwapDate(MyDate &d1, MyDate &d2)
{
MyDate td = d1;
d1 = d2;
d2 = td;
return true;
}
int CalDayNumBetween2Date(MyDate d1, MyDate d2)
{
int num = 0;
int pn = 1; // positive_or_negative
switch(CampDate(d1, d2))
{
case 0:
return 0;
case 1:
SwapDate(d1, d2);
pn = -1;
break;
default:
break;
}
while(!(d1.y == d2.y && d1.m == d2.m && d1.d == d2.d))
{
AddOneDay(d1);
++num;
}
return num * pn;
}
size_t GenTimestamp(const MyDate &d)
{
struct tm stm;
memset(&stm, 0, sizeof(stm));
stm.tm_year = d.y - 1900;
stm.tm_mon = d.m - 1;
stm.tm_mday = d.d;
return mktime(&stm);
}
int CalDayNumBetween2Date2(const MyDate &d1, const MyDate &d2)
{
int diff_secs = (int)GenTimestamp(d2) - (int)GenTimestamp(d1);
if(diff_secs >= 0)
return diff_secs/(3600*24);
else
return (-1 * diff_secs/(3600*24)) * -1;
}