创建一个日期类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++时写的,不太整洁!~

评论