正文

日期运算2006-10-06 11:49:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/xiaoxiaofeng/19060.html

分享到:

创建一个日期类Date(构造,修改,判断日期非法),然后重载各运算符实现:日期-日期,日期-整数,日期+=整数,日期-=整数日期+整数,整数+日期++日期,日期++,--日期,日期--,重载关系运算符,抽取(输入)运算符>>和插入(输出)运算符<<,最后编写一个主函数对以上功能进行全面测试. (使用异常处理机制!) #include<iostream>using namespace std; //-------------------------------普通函数声明-----------------------------//bool isleapyear(int year);                       //判断是否为闰年int daysofmonth(int year,int month);             //计算年、月对应的天数int days(int year,int month,int day);            //计算该日期在本年中是第几天(用于该年为公元后)int ndays(int year,int month,int day);           //计算该日距下一年1月1日有多少天(用于该年为公元前) //前向引用声明class Date;                 //-------------------------------友元函数声明-----------------------------//long operator - (const Date &d1,const Date &d2); //重载日期-日期Date operator - (Date d,int num);          //重载日期-整数Date operator + (int num,Date d);          //重载整数+日期Date operator + (Date d,int num);          //重载日期+整数 bool operator==(const Date &d1,const Date &d2);//重载==运算符bool operator!=(const Date &d1,const Date &d2);//重载!=运算符bool operator>(const Date &d1,const Date &d2); //重载>运算符bool operator<(const Date &d1,const Date &d2); //重载<运算符bool operator>=(const Date &d1,const Date &d2);//重载>=运算符bool operator<=(const Date &d1,const Date &d2);//重载<=运算符 istream &operator >>(istream &in,Date &d);         //重载输入运算符ostream &operator <<(ostream &out,Date &d);        //重载输出运算符 class islegaldate{};                  //定义异常类 //-------------------------------类定义开始-------------------------------//class Date{public: void legaldate();                                   //修改日期,默认21世纪,并判断是否合法    int getyear(){return year;}                                   //得出年份 int getmonth(){return month;}                                 //得出月份 int getday(){return day;}                                     //得出天数 friend long operator - (const Date &d1,const Date &d2);     //重载日期-日期 friend Date operator - (Date d,int num);                      //重载日期-整数 friend Date operator + (int num,Date d);                      //重载整数+日期    friend Date operator + (Date d,int num);                      //重载日期+整数 Date operator += (int num);                                   //重载日期+=整数 Date operator -= (int num);                                   //重载日期-=整数 Date operator ++();                                           //重载++日期    Date operator ++(int p);                                      //重载日期++ Date operator --();                                           //重载--日期 Date operator --(int p);                                      //重载日期-- friend bool operator==(const Date &d1,const Date &d2);        //重载==运算符 friend bool operator!=(const Date &d1,const Date &d2);        //重载!=运算符 friend bool operator>(const Date &d1,const Date &d2);         //重载>运算符 friend bool operator<(const Date &d1,const Date &d2);         //重载<运算符 friend bool operator>=(const Date &d1,const Date &d2);        //重载>=运算符 friend bool operator<=(const Date &d1,const Date &d2);        //重载<=运算符      friend istream &operator >>(istream &in,Date &d);             //重载输入运算符    friend ostream &operator <<(ostream &out,Date &d);            //重载输出运算符private: char date[12]; int year; int month; int day;}; //-------------------------------类定义结束-------------------------------// //-------------------------------类成员函数实现--------------------------------------// //修改日期,默认21世纪,并判断是否合法void Date::legaldate(){ if(strlen(date)!=7&&strlen(date)!=8&&strlen(date)!=9&&strlen(date)!=10&&strlen(date)!=11||(date[0]-48<0&&date[0]-45!=0||date[0]-48>9))        throw islegaldate();  //日期为公元前 if(date[0]>=48&&date[0]<=57) {                             if(strlen(date)==7)  {            //计算日期   year=2*1000+(date[0]-48);   month=(date[2]-48)*10+date[3]-48;   day=(date[5]-48)*10+date[6]-48;   //判断日期的合法性判断分隔符的合法性   if((date[1]!='/' && date[1]!='.' && date[1]!='-')||(date[4]!='/' && date[4]!='.' && date[4]!='-')||(date[1]!=date[4])||year==0||month<1||month>12||day<1||day>daysofmonth(year,month))    throw islegaldate();          //不合法时抛出异常  }  if(strlen(date)==8)  {                            //日期年份为两个字符,默认21世纪   //计算日期   year=2*1000+(date[0]-48)*10+date[1]-48;   month=(date[3]-48)*10+date[4]-48;   day=(date[6]-48)*10+date[7]-48;   //判断日期的合法性   if((date[2]!='/' && date[2]!='.' && date[2]!='-')||(date[5]!='/' && date[5]!='.' && date[5]!='-')||(date[2]!=date[5])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();         //不合法时抛出异常  }  if(strlen(date)==9)  {                            //日期年份为三个字符得出年份为2***   //计算日期   year=2*1000+(date[0]-48)*100+(date[1]-48)*10+date[2]-48;   month=(date[4]-48)*10+date[5]-48;   day=(date[7]-48)*10+date[8]-48;   //判断分隔符的合法性   if((date[3]!='/' && date[3]!='.' && date[3]!='-')||(date[6]!='/' && date[6]!='.' && date[6]!='-')||(date[3]!=date[6])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();           //不合法时抛出异常  }  if(strlen(date)==10)  {                           //日期年份为四个字符,得出相应年份   //计算日期   year=(date[0]-48)*1000+(date[1]-48)*100+(date[2]-48)*10+(date[3]-48);   month=(date[5]-48)*10+date[6]-48;   day=(date[8]-48)*10+date[9]-48;   //判断分隔符的合法性   if((date[4]!='/' && date[4]!='.' && date[4]!='-')||(date[7]!='/' && date[7]!='.' && date[7]!='-')||(date[4]!=date[7])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();             //不合法时抛出异常  } }  //日期为公元后 if(date[0]==45) {                         if(strlen(date)==8)  {   //计算日期   year=-(2*1000+(date[1]-48));   month=(date[3]-48)*10+date[4]-48;   day=(date[6]-48)*10+date[7]-48;   //判断分隔符的合法性   if((date[2]!='/' && date[2]!='.' && date[2]!='-')||(date[5]!='/' && date[5]!='.' && date[5]!='-')||(date[2]!=date[5])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();             //不合法时抛出异常  }  if(strlen(date)==9)  {   //计算日期   year=-(2*1000+(date[1]-48)*10+(date[2]-48));   month=(date[4]-48)*10+date[5]-48;   day=(date[7]-48)*10+date[8]-48;   //判断分隔符的合法性   if((date[3]!='/' && date[3]!='.' && date[3]!='-')||(date[6]!='/' && date[6]!='.' && date[6]!='-')||(date[3]!=date[6])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();            //不合法时抛出异常  }  if(strlen(date)==10)  {   //计算日期   year=2*1000+(date[1]-48)*100+(date[2]-48)*10+date[3]-48;   month=(date[5]-48)*10+date[6]-48;   day=(date[8]-48)*10+date[9]-48;   //判断分隔符的合法性   if((date[4]!='/' && date[4]!='.' && date[4]!='-')||(date[7]!='/' && date[7]!='.' && date[7]!='-')||(date[4]!=date[7])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();            //不合法时抛出异常  }  if(strlen(date)==11)  {   //计算日期   year=-((date[1]-48)*1000+(date[2]-48)*100+(date[3]-48)*10+(date[4]-48));   month=(date[6]-48)*10+date[7]-48;   day=(date[9]-48)*10+date[10]-48;   //判断分隔符的合法性   if((date[5]!='/' && date[5]!='.' && date[5]!='-')||(date[8]!='/' && date[8]!='.' && date[8]!='-')||(date[5]!=date[8])||(year==0||month<1||month>12||day<1||day>daysofmonth(year,month)))    throw islegaldate();            //不合法时抛出异常  } }} //重载日期-日期long operator - (const Date &d1,const Date &d2){ int i; long diff,add1,add2; if(d1.year>0)       //起始日期的年数为公元后时 {  add1=(d1.year-1)*365+days(d1.year,d1.month,d1.day);        //计算起始日期距公元1年1月1日的总天数(不包括它们之间的闰年)  for(i=1;i<d1.year;i++)                    //计算公元1年与起始日期之间有几个闰年,总天数就加上几天   if(isleapyear(i))    add1++; } if(d1.year<0)        //起始日期的年数为公元前时 {  add1=(d1.year+1)*365-ndays(d1.year,d1.month,d1.day);  //计算起始日期距公元1年1月1日的总天数(不包括它们之间的闰年)  for(i=-1;i>d1.year;i--)                       //计算公元1年与起始日期之间有几个闰年,总天数就加上几天   if(isleapyear(i))    add1--; } if(d2.year>0)             //终止日期的年数为公元后时 {  add2=(d2.year-1)*365+days(d2.year,d2.month,d2.day);    //计算终止日期距公元1年1月1日的总天数(不包括它们之间的闰年)  for(i=1;i<d2.year;i++)   if(isleapyear(i))               //计算公元1年与终止日期之间有几个闰年,总天数就加上几天    add2++; } if(d2.year<0)        //终止日期的年数为公元前时 {  add2=(d2.year+1)*365-ndays(d2.year,d2.month,d2.day);  //计算终止日期距公元1年1月1日的总天数(不包括它们之间的闰年)  for(i=-1;i>d2.year;i--)                         //计算公元1年与起始日期之间有几个闰年,总天数就加上几天   if(isleapyear(i))    add2--; } diff=add1-add2;                           //计算起始日期与终止日期的相差天数 return (diff);}  //重载日期-整数Date operator - (Date d,int num){ d=operator + (d,-num); return d;} //重载日期+整数Date operator + (Date d,int num){ //当输入的整数为正数或为0时 if(num>=0) {  if((num+d.day)<=daysofmonth(d.year,d.month))//当相加后天数小于或等于该月的总天数时   d.day=num+d.day;                 //得出的天数为相加后的天数  //当相加后天数大于该月的总天数  else  {   while((num+d.day)>daysofmonth(d.year,d.month))    //当天数加上整数后大于该月份的总天数时   {    num=num-daysofmonth(d.year,d.month);              d.month++;                           //当天数加上整数后大于该月份的总天数时,月份加1    if(d.month>12)                           {     d.year++;     if(d.year==0)                      //排除公元0年,即公元前1年的下一年为公元1年      d.year++;     d.month=1;                         //当月份大于12,年份加1,月份变为1    }   }    d.day=num+d.day;           //当相加后天数小于或等于该月的总天数时,得出的天数为相加后的天数  } }   //当输入的整数为负数时 else {  if((num+d.day)>0)   d.day=num+d.day;     //当相加后天数大于0时,得出的天数为相加后的天数  else                               //当相加后天数小于或等于0时  {   num=num+d.day;   d.month--;                        //当所给日期的天数不够减时,从月份扣除即月份-1   if(d.month<1)                     //当月份小于1时   {    d.year--;                      //当所给日期的月份不够减时,从年份扣除即年份-1    if(d.year==0)d.year--;    d.month=12;                       //月份从1变为12    (12个月为一年)   }   while((num+daysofmonth(d.year,d.month))<0)   {    num=num+daysofmonth(d.year,d.month);    d.month--;    if(d.month<1)    {     d.year--;     if(d.year==0)d.year--;     d.month=12;    }   }   d.day=num+daysofmonth(d.year,d.month);      //当相加后天数大于0时,得出的天数为相加后的天数  } } return d;} //重载整数+日期Date operator + (int num,Date d){    d=operator + (d,num); return d;} //重载日期+=整数Date Date::operator += (int num){ *this=*this+num; return(*this);} //重载日期-=整数Date Date::operator -= (int num){ *this=operator - (*this,num); return(*this);} //重载++日期Date Date::operator ++(){ *this=operator + (*this,1); return(*this);} //重载日期++Date Date::operator++(int p){ Date temp=*this; *this=operator + (*this,1); return temp;} //重载--日期Date Date::operator --(){    *this=operator - (*this,1); return(*this);} //重载日期--Date Date::operator -- (int p){ Date temp=*this; *this=operator - (*this,1); return temp;}                                         //重载==运算符bool operator==(const Date &d1,const Date &d2){ if(d1.year==d2.year&&d1.month==d2.month&&d1.day==d2.day)  return true; else return false;} //重载!=运算符bool operator!=(const Date &d1,const Date &d2){ if(d1.year!=d2.year||d1.month!=d2.month||d1.day!=d2.day)  return true; else return false;}//重载>运算符bool operator>(const Date &d1,const Date &d2){ if(d1-d2>0)return true; else return false;} //重载<运算符bool operator<(const Date &d1,const Date &d2){ if(d1-d2<0)return true; else return false;} //重载>=运算符bool operator>=(const Date &d1,const Date &d2){ if(d1-d2>0||d1-d2==0)return true; else return false;} //重载<=运算符bool operator<=(const Date &d1,const Date &d2){    if(d1-d2<0||d1-d2==0)return true; else return false;} //重载输入运算符istream &operator >>(istream &in,Date &d){ in>>d.date; return in;} //重载输出运算符ostream &operator <<(ostream &out,Date &d){ out<<"("<<d.getyear()<<","<<d.getmonth()<<","<<d.getday()<<")"; return out;} //-------------------------------类成员函数实现结束--------------------------------------// //-------------------------------普通函数成员实现-----------------------------------// //判断是否为闰年bool isleapyear(int year) { if(year>0) {  if ((year%4==0 && year%100!=0)||(year%400==0))   return true;  else return false; }    if(year<0) {  if (((year+1)%4==0 && (year+1)%100!=0)||((year+1)%400==0))   return true;  else return false; } return true;}  //计算年、月对应的天数int daysofmonth(int year,int month){ int day_num[]={-1,31,-1,31,30,31,30,31,31,30,31,30,31}; if (month!=2)  return day_num[month]; else  return (isleapyear(year)?29:28);}   //计算该日期在本年中是第几天(用于该年为公元后)int days(int year,int month,int day){ int days; switch(month) { case 1:days=day;break; case 2:days=day+31;break; case 3:days=day+59;break; case 4:days=day+90;break; case 5:days=day+120;break; case 6:days=day+151;break; case 7:days=day+181;break; case 8:days=day+212;break; case 9:days=day+243;break; case 10:days=day+273;break; case 11:days=day+304;break; case 12:days=day+334;break; } if((year%4==0&&year%100!=0||year%400==0)&&month>2)//当该年为闰年时,2月份的总天数为29天  days++; return (days);  } //计算该日距下一年1月1日有多少天(用于该年为公元前)int ndays(int year,int month,int day){ int days; switch(month) { case 1:days=334+31-day;break; case 2:days=306+28-day;break; case 3:days=275+31-day;break; case 4:days=245+30-day;break; case 5:days=214+31-day;break; case 6:days=184+30-day;break; case 7:days=153+31-day;break; case 8:days=122+31-day;break; case 9:days=92+30-day;break; case 10:days=61+31-day;break; case 11:days=31+30-day;break; case 12:days=31-day;break; } //该年为闰年,月数小于3时,该日距下一年1月1日的天数须加上2月29这一天 if(((year+1)%4==0&&(year+1)%100!=0||(year+1)%400==0)&&(month<3))  days++; return (days);} //-------------------------------普通函数成员实现结束-----------------------------------// //---------------------------------主函数开始-----------------------------------//int main(){ Date d1,d2,d3; int num; double diff; char choice; do{  cout<<"请输入第一个日期(年月日),要求月份和日期都为两个字符,如2001/03/01  :"<<endl;    //输入日期,默认中式输入  for(;;)  {   try   {    cin>>d1;    d1.legaldate();break;   }     catch(islegaldate)   { //处理异常    cout<<"输入日期不合法!请重新输入!"<<endl<<"请输入第一个日期(年月日),要求月份和日期都为两个字符,如2001/03/01  :"<<endl;   }  }  cout<<"请输入第二个日期(年月日),要求月份和日期都为两个字符,如2001/03/01  :"<<endl;  for(;;)  {   try   {    cin>>d2;    d2.legaldate(); break;   }   catch(islegaldate)   {  //处理异常    cout<<"输入日期不合法!请重新输入!"<<endl<<"请输入第二个日期(年月日),要求月份和日期都为两个字符,如2001/03/01  :"<<endl;   }  }  cout<<"请输入一个整数:";  cin>>num;  diff=d1-d2;  cout<<"两个日期之间相差"<<diff<<"天"<<endl;  if(d1==d2)   cout<<"d1=d2="<<d1<<endl;  if(d1!=d2)   cout<<"d1!=d2"<<endl;  if(d1>d2)   cout<<"d1>d2"<<endl;  if(d1<d2)   cout<<"d1<d2"<<endl;  if(d1>=d2)   cout<<"d1>=d2"<<endl;  if(d1<=d2)   cout<<"d1<=d2"<<endl;  d3=d1+num;  cout<<d1<<"+"<<num<<"="<<d3<<endl;  d3=num+d1;  cout<<num<<"+"<<d1<<"="<<d3<<endl;  cout<<"现在第一个日期d1为:"<<d1<<endl;  d1+=num;  cout<<"经d1+="<<num<<"后,d1变为:"<<d1<<endl;  d3=d1-num;  cout<<d1<<"-"<<num<<"="<<d3<<endl;  cout<<"现在第一个日期d1为:"<<d1<<endl;  d1-=num;  cout<<"经d1-="<<num<<"后,d1变为:"<<d1<<endl;  cout<<"现在第一个日期d1为:"<<d1<<endl<<"现在第三个日期d3为:"<<d3<<endl;  d3=++d1;  cout<<"经d3=++d1运算后,"<<"d1="<<d1<<","<<"d3="<<d3<<endl;        cout<<"现在第一个日期d1为:"<<d1<<endl<<"现在第三个日期d3为:"<<d3<<endl;  d3=d1++;  cout<<"经d3=d1++运算后,"<<"d1="<<d1<<","<<"d3="<<d3<<endl;  cout<<"现在第一个日期d1为:"<<d1<<endl<<"现在第三个日期d3为:"<<d3<<endl;  d3=--d1;   cout<<"经d3=--d1运算后,"<<"d1="<<d1<<","<<"d3="<<d3<<endl;  cout<<"现在第一个日期d1为:"<<d1<<endl<<"现在第三个日期d3为:"<<d3<<endl;  d3=d1--;  cout<<"经d3=d1--运算后,"<<"d1="<<d1<<","<<"d3="<<d3<<endl;  cout<<"是否继续?(Y/N): ";  cin>>choice; } while(choice=='y'||choice=='Y'); return 0;}//---------------------------------主函数结束-----------------------------------//     初学C++时写的,不太整洁!~

阅读(277) | 评论(3)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册