日期类与时间类定义(运算符重载应用)

日期类定义(运算符重载应用):

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;
}