求一算法:计算任意两个日期之间的天数。

时间:2021-12-17 00:17:12
计算任意两个日期之间的天数

比如说计算 20040506-20050201之间的天数
虽然我自己也写了一个,可是写的太次了

以前我在一本c++的书上看到过这个算法的,不过记不起来了啊 

请高手帮忙!

6 个解决方案

#1


可以用mfc 的CTimeSpan类

#2


呵呵,我想应该时有这样的函数的。如果自己写,不难,但是累赘,我们得知道4得倍数年位闰年,还要知道各各月为大月,小月,呵呵。

#3


当两日期在同一个月时用大数减小数加一即可,至于不在同一个月内我占时还没想好,不好意思我水平太菜了,大家见笑了

#4


呵呵,我写得可以参考:

#include<iostream>
#include <string.h>
using namespace std;



bool isDigit(const char* str)
{     //判断该字符串是否为有效得数字串      
                                                              
int i = 0;
int len = strlen(str);
while (i<len)
{
if (!isdigit(str[i]))
return false;
i++;

return true;
}
bool isMonthAndDateOk(bool isLeapYear, int m, int d)
{//检测该年的天数是否符合常理
switch(m)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (d>31)
return false;
break;
case 2:
if (isLeapYear)
{
if(d>29)
return false;
}
else
{
if(d>28)
return false;
}
break;
case 4:
case 6:
case 9:
case 11:
if (d>30)
return false;
break;
default:
break;
}
return true;
}
double countMonthDays(double &days, bool isLeapYear, int m, int d)
{//计算该年m个月得天数,包括m月得d天
int i;
for (i=1; i<=m; i++)
{

switch(i)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days += 31;
break;
case 2:
if (isLeapYear)
{
days += 29;
}
else
{
days+= 28;
}
break;
case 4:
case 6:
case 9:
case 11:
days += 30;
break;
default:
break;
}
}
days += d;
return days;
}

double getDays(char* beg, char* end)
{//计算两个日期之间得天数,日期格式为:
//char beg[] = "20020406";
//char end[] = "20080406"; 字符串
//失败返回-1

bool begIsLeapYear, endIsLeapYear;
char* pbeg, *pend, *temp;
pbeg = beg;
pend = end;
char bcYear[5],ecYear[5];
char bcMonth[3],ecMonth[3];
char bcDate[3],ecDate[3];
int bdYear,bdMonth,bdDate,edYear,edMonth,edDate;
double bDays=0, eDays=0;
int i;
if ((strlen(pbeg) != 8) || (strlen(pend) != 8))
goto ERR;
if (!isDigit(pbeg) || !isDigit(pend))
goto ERR;
if (strcmp(pbeg, pend) > 0)
{
pbeg = end;
pend = beg;
}
memcpy (bcYear, pbeg, 4);
memcpy (ecYear, pend, 4);
memcpy (bcMonth, pbeg+4, 2);
memcpy (ecMonth, pend+4, 2);
memcpy (bcDate, pbeg+6, 2);
memcpy (ecDate, pend+6, 2);
bdYear = atoi(bcYear);
edYear = atoi(ecYear);
bdMonth = atoi(bcMonth);
edMonth = atoi(ecMonth);
bdDate = atoi(bcDate);
edDate = atoi(ecDate);
if ((bdMonth>12) || (edMonth>12))
goto ERR;
begIsLeapYear = (bdYear%4 == 0)?true:false;
if (!isMonthAndDateOk(begIsLeapYear, bdMonth, bdDate))
goto ERR;
endIsLeapYear = (edYear%4 == 0)?true:false;
if (!isMonthAndDateOk(endIsLeapYear, edMonth, edDate))
goto ERR;

countMonthDays(bDays, begIsLeapYear, bdMonth, bdDate);
countMonthDays(eDays, endIsLeapYear, edMonth, edDate);
eDays -= bDays;
for (i=bdYear; i<edYear; i++)
{
if (i%4 == 0)
eDays += 366;
else
eDays += 355;
}


cout<<bdYear<<" "<<bdMonth<<" "<<bdDate<<endl;
cout<<edYear<<" "<<edMonth<<" "<<edDate<<endl;

return eDays;
ERR:
return -1;

}
int main()
{
char beg[] = "20020406";
char end[] = "20080406";
double days = getDays(beg,end);
cout<<days<<endl;
return 0;
}

#5


#include <iostream.h>
int leapyear(int);
long int alldays(int,int,int);
int main()
{int year,month,day;
 long int day1,day2,day1s,day2s,i;
 
 cout<<"请输入第一个日期:";
 cin>>day1;
 year=day1/10000;
 month=(day1/100)%100;
 day=day1%100;
 day1s=alldays(year,month,day);
 cout<<"请输入第二个日期:";
  cin>>day2;
 year=day2/10000;
 month=(day2/100)%100;
 day=day2%100;
 day2s=alldays(year,month,day);
 if(day1s>day2s)
 i=day1s-day2s;
   else
   i=day2s-day1s;
   cout<<"两个日期相差"<<i<<"天";
   return 0;
}
int leapyear(int year)
{ if(year%4==0&&year%100!=0||year%400==0)
   return 1;
 else
 return 0;
}
long int alldays(int year,int month,int day)
{int i,j;
 long int days,daym,dayy;
   days=0;
 for(i=1;i<year;i++)
 { j=leapyear(i);
   if(j==1)
   days=days+366;
    else if(j==0)
days=days+365;
 }
 daym=days;
 j=leapyear(year); 
 for(i=1;i<month;i++)
  {if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)
daym=daym+31;
 else if(i==4||i==6||i==9||i==11)
 daym=daym+30;
       else if(i==2)
   {if(j==1)
   daym=daym+29;
    else if(j==0)
daym=daym+28;
}
 }
dayy=daym;
  dayy=dayy+day;
  return dayy;
 }

不过没判断你的输入是否合法^^

#6


我把主函数改动了一下,这样可以连续输入了:
int main()
{
char beg[] = "20020406";
char end[] = "20080406";
double days = 0;
while(1)
{
cout<<"Please input begin date: as yyyymmdd: "<<endl;
cin>>beg;
cout<<endl;
cout<<"Please input end date: as yyyymmdd: "<<endl;
cin>>end;
cout<<endl;
if ((days=getDays(beg,end))<0)
{
cout<<"Your date is wrong! Is your date like as 20040722 ?"<<endl;
}
else
cout<<days<<endl;
}
return 0;
}

#1


可以用mfc 的CTimeSpan类

#2


呵呵,我想应该时有这样的函数的。如果自己写,不难,但是累赘,我们得知道4得倍数年位闰年,还要知道各各月为大月,小月,呵呵。

#3


当两日期在同一个月时用大数减小数加一即可,至于不在同一个月内我占时还没想好,不好意思我水平太菜了,大家见笑了

#4


呵呵,我写得可以参考:

#include<iostream>
#include <string.h>
using namespace std;



bool isDigit(const char* str)
{     //判断该字符串是否为有效得数字串      
                                                              
int i = 0;
int len = strlen(str);
while (i<len)
{
if (!isdigit(str[i]))
return false;
i++;

return true;
}
bool isMonthAndDateOk(bool isLeapYear, int m, int d)
{//检测该年的天数是否符合常理
switch(m)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (d>31)
return false;
break;
case 2:
if (isLeapYear)
{
if(d>29)
return false;
}
else
{
if(d>28)
return false;
}
break;
case 4:
case 6:
case 9:
case 11:
if (d>30)
return false;
break;
default:
break;
}
return true;
}
double countMonthDays(double &days, bool isLeapYear, int m, int d)
{//计算该年m个月得天数,包括m月得d天
int i;
for (i=1; i<=m; i++)
{

switch(i)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days += 31;
break;
case 2:
if (isLeapYear)
{
days += 29;
}
else
{
days+= 28;
}
break;
case 4:
case 6:
case 9:
case 11:
days += 30;
break;
default:
break;
}
}
days += d;
return days;
}

double getDays(char* beg, char* end)
{//计算两个日期之间得天数,日期格式为:
//char beg[] = "20020406";
//char end[] = "20080406"; 字符串
//失败返回-1

bool begIsLeapYear, endIsLeapYear;
char* pbeg, *pend, *temp;
pbeg = beg;
pend = end;
char bcYear[5],ecYear[5];
char bcMonth[3],ecMonth[3];
char bcDate[3],ecDate[3];
int bdYear,bdMonth,bdDate,edYear,edMonth,edDate;
double bDays=0, eDays=0;
int i;
if ((strlen(pbeg) != 8) || (strlen(pend) != 8))
goto ERR;
if (!isDigit(pbeg) || !isDigit(pend))
goto ERR;
if (strcmp(pbeg, pend) > 0)
{
pbeg = end;
pend = beg;
}
memcpy (bcYear, pbeg, 4);
memcpy (ecYear, pend, 4);
memcpy (bcMonth, pbeg+4, 2);
memcpy (ecMonth, pend+4, 2);
memcpy (bcDate, pbeg+6, 2);
memcpy (ecDate, pend+6, 2);
bdYear = atoi(bcYear);
edYear = atoi(ecYear);
bdMonth = atoi(bcMonth);
edMonth = atoi(ecMonth);
bdDate = atoi(bcDate);
edDate = atoi(ecDate);
if ((bdMonth>12) || (edMonth>12))
goto ERR;
begIsLeapYear = (bdYear%4 == 0)?true:false;
if (!isMonthAndDateOk(begIsLeapYear, bdMonth, bdDate))
goto ERR;
endIsLeapYear = (edYear%4 == 0)?true:false;
if (!isMonthAndDateOk(endIsLeapYear, edMonth, edDate))
goto ERR;

countMonthDays(bDays, begIsLeapYear, bdMonth, bdDate);
countMonthDays(eDays, endIsLeapYear, edMonth, edDate);
eDays -= bDays;
for (i=bdYear; i<edYear; i++)
{
if (i%4 == 0)
eDays += 366;
else
eDays += 355;
}


cout<<bdYear<<" "<<bdMonth<<" "<<bdDate<<endl;
cout<<edYear<<" "<<edMonth<<" "<<edDate<<endl;

return eDays;
ERR:
return -1;

}
int main()
{
char beg[] = "20020406";
char end[] = "20080406";
double days = getDays(beg,end);
cout<<days<<endl;
return 0;
}

#5


#include <iostream.h>
int leapyear(int);
long int alldays(int,int,int);
int main()
{int year,month,day;
 long int day1,day2,day1s,day2s,i;
 
 cout<<"请输入第一个日期:";
 cin>>day1;
 year=day1/10000;
 month=(day1/100)%100;
 day=day1%100;
 day1s=alldays(year,month,day);
 cout<<"请输入第二个日期:";
  cin>>day2;
 year=day2/10000;
 month=(day2/100)%100;
 day=day2%100;
 day2s=alldays(year,month,day);
 if(day1s>day2s)
 i=day1s-day2s;
   else
   i=day2s-day1s;
   cout<<"两个日期相差"<<i<<"天";
   return 0;
}
int leapyear(int year)
{ if(year%4==0&&year%100!=0||year%400==0)
   return 1;
 else
 return 0;
}
long int alldays(int year,int month,int day)
{int i,j;
 long int days,daym,dayy;
   days=0;
 for(i=1;i<year;i++)
 { j=leapyear(i);
   if(j==1)
   days=days+366;
    else if(j==0)
days=days+365;
 }
 daym=days;
 j=leapyear(year); 
 for(i=1;i<month;i++)
  {if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)
daym=daym+31;
 else if(i==4||i==6||i==9||i==11)
 daym=daym+30;
       else if(i==2)
   {if(j==1)
   daym=daym+29;
    else if(j==0)
daym=daym+28;
}
 }
dayy=daym;
  dayy=dayy+day;
  return dayy;
 }

不过没判断你的输入是否合法^^

#6


我把主函数改动了一下,这样可以连续输入了:
int main()
{
char beg[] = "20020406";
char end[] = "20080406";
double days = 0;
while(1)
{
cout<<"Please input begin date: as yyyymmdd: "<<endl;
cin>>beg;
cout<<endl;
cout<<"Please input end date: as yyyymmdd: "<<endl;
cin>>end;
cout<<endl;
if ((days=getDays(beg,end))<0)
{
cout<<"Your date is wrong! Is your date like as 20040722 ?"<<endl;
}
else
cout<<days<<endl;
}
return 0;
}