在学C++类的时候,日期类是一个很基础也很重要的类,所以有必要实现一下。
常规日期类的本身并不复杂,实现的过程主要涉及到了一些构造函数,拷贝构造函数,以及各种运算符的重载等,而难点主要在于如何保证日期的有效性,比如我们知道年必须为正数,月都是1-12之间的整数,各个月的天数不同以及闰年2月天数的变化等等,如何将这些体现在我们对于一个日期类对象进行自增,自减以及加减多少天得出正确的日期等运算中。
下面先给出类的定义:
#include<iostream>
using namespace std;
class Date
{
friend istream& operator>>(istream& scin,Date& d);
friend ostream& operator<<(ostream& scout,Date& d);
public:
Date(int year = 1900, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
Date(const Date& d)
{
_year=d._year;
_month=d._month;
_day=d._day;
}
Date& operator=(const Date& d)
{
if(*this != d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
void Display()
{
cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
}
static int GetMonthDays(int year,int month)
{
if(year<1900||month<1||month>12)
{
return -1;
}
static int arr[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int days = arr[month];
if(month == 2 && IsLeapYear(year))
{
days++;
}
return days;
}
static bool IsLeapYear(int year)
{
return (year%4 == 0 && year%100 != 0 || year%400 == 0);
}
bool IsInvalid() //判断日期是否合法
{
if (_year>=1900 && _month>0 && _month<13 && _day>0 && _day<=GetMonthDays(_year,_month))
{
return true;
}
else
{
return false;
}
}
bool operator>(const Date& d)const
{
if(_year>d._year)
{
return true;
}
else if(_year==d._year)
{
if(_month>d._month)
{
return true;
}
else if(_month == d._month)
{
if(_day>d._day)
{
return true;
}
}
}
return false;
}
bool operator==(const Date& d)const
{
return (_year==d._year && _month==d._month && _day==d._day);
}
bool operator>=(const Date& d)const
{
return (*this>d && *this==d);
}
bool operator<(const Date& d)
{
return !(*this >= d);
}
bool operator<=(const Date& d)
{
return !(*this>d);
}
bool operator!=(const Date& d)
{
return !(*this == d);
}
Date operator+(int day)
{
if(day<0)
{
return (*this)-(-day);
}
Date tmp = *this;
tmp._day+=day;
while(tmp.IsInvalid() == false)
{
tmp._day-=GetMonthDays(tmp._year,tmp._month);
if(tmp._month == 12)
{
tmp._year++;
tmp._month=1;
}
else
{
tmp._month++;
}
}
return tmp;
}
Date& operator+=(int day)
{
*this = *this+day;
return *this;
}
int operator-(const Date& d)
{
Date Big;
Date Small;
int count = 0;
if(*this<d)
{
Small = *this;
Big = d;
}
else
{
Small = d;
Big = *this;
}
while(!(Small == Big))
{
Small++;
count++;
}
return count;
}
Date operator++()
{
*this=*this+1;
return *this;
}
Date operator++(int)
{
Date tmp = *this;
*this=*this+1;
return tmp;
}
Date operator--()
{
*this=*this-1;
return *this;
}
Date operator--(int)
{
Date tmp = *this;
*this=*this-1;
return tmp;
}
private:
int _year;
int _month;
int _day;
};
istream& operator>>(istream& scin,Date& d)
{
cout<<"输入年月日"<<endl;
scin>>d._year;
scin>>d._month;
scin>>d._day;
return scin;
}
ostream& operator<<(ostream& scout,Date& d)
{
scout<<d._year<<"-"<<d._month<<"-"<<d._day<<endl;
return scout;
}
void Test1()
{
Date d1(1998,05,23);
Date d2;
d2=d1+100;
cout<<d2<<endl;
Date d3(1997,6,30);
int d4;
d4=d3-d1;
cout<<d4<<endl;
Date d5(1998,5,23);
int d;
d=d1==d5;
cout<<d<<endl;
d=d1==d3;
cout<<d<<endl;
}
int main()
{
Test1();
return 0;
}
运行结果:
验证如下:
下面验证一下比较特殊的二月:
void Test1()
{
Date d1(1998,2,23);
Date d2;
d2=d1+100;
cout<<d2<<endl;
Date d3(1997,2,23);
int d4;
d4=d3-d1;
cout<<d4<<endl;
Date d5(1998,5,23);
int d;
d=d1==d5;
cout<<d<<endl;
d=d1==d3;
cout<<d<<endl;
}
经过验证,此程序是正确的。