【C++】日期类实现

一. 日期类介绍

日期类 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;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值