日期类与时间类定义(运算符重载应用)
日期类与时间类定义(运算符重载应用)
日期类定义(运算符重载应用):
class Data //起初只是用来表示出版日期,后来发现借阅与归还日期都可用
{
int year;
int month;
int day;
public:
Data(){};
Data(int year1,int month1,int day1):year(year1),month(month1),day(day1){};
friend ostream&operator<<(ostream&os,const Data&d);
friend istream&operator>>(istream&is,Data&d);
bool operator<(const Data &d)const //日期比较函数
{return year!=d.year?year<d.year:month!=d.month?month<d.month:day<d.day;}
int operator-(Data d) //对日期的操作,可以直接按月份进行两个月的相减操作,也可以按如下方式进行精确一点的操作(还可以判断平年闰年进行更精确的操作)
{
if(year<d.year||(year==d.year&&month<d.month)||(year==d.year&&month==d.month&&day<d.day))
return -1; //当日期没有办法相减(后面的日期大时)
int m[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //按下标(对应月份)补齐,第一个数不计,对于每年的二月按28天计(不考虑平年闰年)
int count=0;
int a=d.year,b=d.month,c=d.day;
while(1)
{
if(this->year==a&&this->month==b&&this->day==c) break;
if(c==m[b]){
c=1;
if(b==12)
{
b=1;
a++;
}
else b++;
}
else c++;
count++;
}
return count;
}
Data operator+ (int x)
{
int m[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //按下标(对应月份)补齐,第一个数不计,对于每年的二月按28天计(不考虑平年闰年)
while(x--)
{
if(day==m[month])
{
day=1;
if(month==12)
{
year++;
month=1;
}
else month++;
}
else day++;
}
return *this;
}
};
istream&operator>>(istream&is,Data&d) //先重载出版日期的输入输出
{
while(1)
{
is>>d.year>>d.month>>d.day;
if(d.year<1900||d.year>2019||d.month<1||d.month>12||d.day<1||d.day>31); //这里可以优化为判断闰年或平年然后进行判断
else break;
}
return is;
}
ostream&operator<<(ostream&os,const Data&d)
{
//os<<"year:"<<d.year<<" "<<"month:"<<d.month<<" "<<"day:"<<d.day;
//为了输入输出相统一,改为下面的输出形式
os<<d.year<<" "<<d.month<<" "<<d.day;
return os;
}
时间类定义(运算符重载应用):
class Time
{
int year,month,day,hour,min;
string s;
public:
Time() {};
~Time() {};
Time(int year1,int month1 ,int day1,int hour1,int min1):year(year1),month(month1),day(day1),hour(hour1),min(min1) {};
friend istream& operator>>(istream&,Time&t);
friend ostream& operator<< (ostream&,const Time&t);
int operator- (Time t) //重载运算符"-"在类内定义,类外定义由于year,month等是私有的,需使用get函数获取数据,没有必要
{ //直接定义即可,不必使用引用,一开始觉得都一样,使用了引用,后来发现错误没法调了,调了很久才发现,使用引用后减号后面的值会变为减号前的值,两个值就一样了
if((year<t.year)||(year==t.year&&month<t.month)||(year==t.year&&month==t.month&&day<t.day)||(year==t.year&&month==t.month&&day==t.day&&hour<t.hour)||year==t.year&&month==t.month&&day==t.day&&hour==t.hour&&min<t.min)
return -1;
int countyear=0;
int countmonth=0;
int countday=0;
int counthour=0;
int countmin=0;
int m[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //按下标(对应月份)补齐,第一个数不计,对于每年的二月按28天计(不考虑平年闰年)
while(1)
{
if(this->year==t.year&&this->month==t.month&&this->day==t.day&&hour==t.hour&&min==t.min) break;
if(t.min==60)
{
t.hour++;
counthour++;
t.min=0;
if(t.hour==24)
{
t.day++;
countday++;
t.hour=0;
if(t.day>m[t.month]) //上述日期末尾天数是存在的,如果写"==",则直接跳过,不符实际
{
t.month++;
countmonth++;
t.day=1;
if(t.month>12) //12月是存在的
{
t.year++;
countyear++;
t.month=1;
}
}
}
}
else {t.min++;countmin++;}
}
//cout<<countyear<<" "<<countmonth<<" "<<countday<<" "<<counthour<<" "<<countmin<<endl;
return countmin;
}
//Time operator+ (int i); //利用"-"操作可以代替"+"
//对于时间的比较,一开始不打算用的,不过后面的登录以及对用户对待出行车票的查看都需要用到
bool operator< (const Time&t)const
{
return year!=t.year?year<t.year:month!=t.month?month<t.month:day!=t.day?day<t.day:hour!=t.hour?hour<t.hour:min<t.min;
}
bool operator== (const Time&t)const
{
return year==t.year&&month==t.month&&day==t.day&&hour==t.hour&&min==t.min;
}
};
istream&operator>>(istream&in,Time&t)
{
while(1) //使用循环也好也不好,当程序运行时用户输入时间可以重新输入,但当文件内的时间有误时,程序会一直循环
{
//in>>t.year>>t.s>>t.month>>t.s>>t.day>>t.s>>t.hour>>t.s>>t.min;
in>>t.year>>t.month>>t.day>>t.hour>>t.min;
if(t.year>2000&&t.year<=2019&&t.month>=1&&t.month<=12&&t.day>=1&&t.day<=31&&t.hour>=0&&t.hour<=23&&t.min>=0&&t.min<60) //对时间进行限制,还应注意过时车票不可买(查询也不可查,这可以在登录时间上作要求)
break;
else cout<<"Time error,请重试:"<<endl;
}
return in;
}
ostream&operator<<(ostream&out,const Time&t)
{
out<<t.year<<" "<<t.month<<" "<<t.day<<" "<<t.hour<<" "<<t.min;
return out;
}
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。