这里写目录标题
一. 日期类介绍
日期类 Date,包括年、月、日等私有数据成员。要求实现对日期的基本运算,比如:
- 两个日期的比较
- 日期加减天数
- 日期自增和自减
- 日期减日期等(使用运算符重载)
二. 日期类实现代码
#include<iostream>
using namespace std;
class Date
{
public:
// 获取某年某月的天数
static int GetMonthDay(int year, int month)
{
// 该年为平年的时候(2月只有28天)
int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
// 若该年为闰年,月份为2月
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
{
return 29;
}
return monthDays[month];
}
// 全缺省的构造函数
Date(int year = 0, int month = 1, int day = 1)
{
// 判断输入的时间是否合法
if (year >= 0 && (month >= 1 && month <= 12) && (day >= 1 && day <= GetMonthDay(year, month)))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "输入非法" << endl;
}
}
// 拷贝构造函数
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 打印某月某月某日
void Print() const
{
cout << _year << " - " << _month << " - " << _day << endl;
}
// >运算符重载
// 调用:d1 > d2 等价于 d1.operator>(&d1,d2)
bool operator > (const Date& d) const
{
// *this和d比较
if (_year > d._year) //年大的就大
{
return true;
}
else if (_year == d._year&&_month > d._month) //年相同月大的就大
{
return true;
}
else if (_year == d._year&&_month == d._month&&_day > d._day) //年和月相同天大的就大
{
return true;
}
return false; //上面都不符合,那么*this就小于d
}
// ==运算符重载
// 调用:d1 == d2 等价于 d1.operator==(&d1,d2)
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) const
{
return !(*this >= d);
}
// <= 运算符重载
// 复用了上面的 > 重载运算符的代码
bool operator<=(const Date& d) const
{
return !(*this > d);
}
// != 运算符重载
// 复用了上面的 == 重载运算符的代码
bool operator!=(const Date& d) const
{
return !(*this == d);
}
// 赋值运算符的重载
// 赋值表达式的结果是赋值之后的的值,所以返回 *this,返回类型为 Date&
Date& operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
// 日期 += 天数
// 操作数本身增加了,表达式的结果为加之后的操作数本身,所以返回 *this,返回类型为 Date&
Date& operator+=(int day)
{
if (day < 0) //处理类似 d1+=(-100) 这种情况,复用了 -= 重载操作符
{
return *this -= (-day);
}
// 先把天数加上
_day += day;
// 天数加了之后若大于当月的天数,要往前进一个月
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
//进月后还需要判断是否要往前进一年
if (_month == 13)
{
_year++;
_month = 1;
}
}
// 返回值
return *this;
}
// 日期 + 天数
// 复用了上面的 += 重载运算符
// 操作数本身不改变,表达式的结果为加之后的值,但操作数本身是不会改变的
Date operator+(int day) const
{
Date d(*this);
d += day;
return d;
}
// 日期 -= 天数
// 操作数本身减少了,表达式的结果为减之后的操作数本身,所以返回 *this,返回类型为 Date&
Date& operator-=(int day)
{
if (day < 0) //处理类似 d1-=(-100)这种情况,复用了-=重载操作符
{
return *this += (-day);
}
//先把天数减了
_day -= day;
//天数减了之后若小于等于0,要往前借一个月
while (_day <= 0)
{
_month--;
//往前借了一个月之后,若月份为0,再往前借一年
if (_month == 0)
{
_month = 12;
_year--;
}
_day = GetMonthDay(_year, _month) + _day;
}
return *this;
}
// 日期 - 天数
// 复用了上面的 -= 重载运算符
// 操作数本身不改变,表达式的结果为减之后的值,但操作数本身是不会改变的,所以返回 d(*this),返回值类型为 Date
Date operator-(int day) const
{
Date d(*this);
d -= day;
return d;
}
// 前置++
// 本身加 1,返回加之后的值,即 *this,所以返回类型为 Date&
Date& operator++()
{
*this += 1;
return *this;
}
// 后置++
// 本身加 1,返回加之前的值,即 d(*this加1之前的拷贝),所以返回类型为 Date
// 调用时,若为后置++,编译器自动识别会默认传入一个整型实参,来调用这个后置++重载操作符代码
Date operator++(int)
{
Date d(*this);
++(*this);
return d;
}
// 前置--
// 本身减 1,返回减之后的值,即 *this,所以返回类型为 Date&
Date& operator--()
{
*this -= 1;
return *this;
}
// 后置--
// 本身减 1,返回减之前的值,即 d(*this减1之前的拷贝),所以返回类型为 Date
// 调用时,若为后置 --,编译器自动识别会默认传入一个整型实参,来调用这个后置--重载操作符代码
Date operator--(int)
{
Date d(*this);
--(*this);
return d;
}
// 日期-日期 返回天数
int operator-(const Date& d) const
{
int flag = 1; //处理小日期减大日期得到负天数的情况
Date max = *this;
Date min = d;
// max为大的日期
// min为小的日期
if (*this < d)
{
flag = -1;
Date tmp(max);
max = min;
min = tmp;
}
int count = 0;//统计相差的天数
while (max != min)
{
++min;
++count;
}
return count * flag;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2021, 3, 14);
Date d2(2021, 3, 31);
//测试代码
//cout << (d1 <= d2) << endl;
//d1 = d2;
//Date d3 = (d1 + 10);
//(d1+30).Print();
//(d1+=30).Print();
//(d1-30).Print();
//(d1 + 30).Print();
//++d2;
//(d1--).Print();
//d1.Print();
//cout << d2 - d1 << endl;
return 0;
}