设计并实现日期类Date,它至少包含下列特性:

(1)可以建立具有指定日期(指定年、月、日)的Date对象,默认的日期是1949.10.1;

(2)可以从输入流读一个日期到一个Date对象,日期的输人格式是:年.月.日,其中年可以是4位数字也可以是2位数字(即可省略20),月、日可以是2位数字也可以是1位数字;
(3)可以通过输出流输出一个Date对象,格式与输入同;
(4)可以用==、!=、<、<=、>和>=等运算符对两个Date对象进行比较;
(5)可以用++、--(前缀及后缀)、+=、-=等运算符完成增减1天或若干天的操作;
(6)可以用+、-将一个Date对象与一个表示天数的整数相加减,其结果是一个表示若干天前或若干天后的日期的Date对象。

cpp 复制代码
class Date
{
private:
	int year, month, day;
	//校验闰年 返回day = 29
	bool isLeapYear()const
	{
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
	int getDaysOfMonth()const
	{
		int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && isLeapYear())
		{
			return 29;
		}
		//返回月份对应的天数
		return days[month];
	}
	bool isValidDate()const
	{
		//校验日期合法性
		if (year < 1 || month < 1 || month > 12 || day < 1)
		{
			return false;
		}
		return day <= getDaysOfMonth();
	}
	//返回四位数年份
	int normalizeYear(int y)const
	{
		if (y>=0 && y<100)
		{
			return 2000 + y;
		}
		return y;
	}
	void adjustDatr()
	{
		while (day < 1)
		{
			if (--month < 1)
			{
				month = 12;
				year--;
			}
			day += getDaysOfMonth();
			//成功+=后跳出循环
		}
		while (day > getDaysOfMonth())
		{
			day -= getDaysOfMonth();
			if (++month > 12)
			{
				month = 1;
				year++;
			}
		}
	}
	//问题1 可以建立具有指定日期(指定年、月、日)的Date对象,默认的日期是1949.10.1;
public:
	Date(int y = 1949, int m = 10, int d = 1) :year(normalizeYear(y)), month(m), day(d)
	{
		//非法日期自动重置为默认值,符合指定日期的不会进入这里,不符合才会重置
		if (!isValidDate())
		{
			year = 1949;
			month = 10;
			day = 1;
		}
	}
	//流运算符 << 输出运算符
	friend ostream& operator<<(ostream& out, const Date& date)
	{
		//sprintf 是把内容输出到内存中的字符串数组里。
		char buf[20];
		sprintf(buf, "%d.%d.%d", date.year, date.month, date.day);
		out << buf;
		return out;
	}
	//流运算符 >> 输入流运算符
	//支持2位/4位年份,1/2位月,日
	friend istream& operator>>(istream& in, Date& date2)
	{
		string s;
		in >> s;
		int y, m, dy;
		//将s的字符串的内容通过s_str()转换成C风格,因为sscanf只接纳C风格
		//"%d.%d.%d" 通过这样的形式输入提取三个整数数据,看看是否等于3,如果是2026/2/19,提取的整数数据小于3
		if (sscanf(s.c_str(),"%d.%d.%d",&y,&m,&dy) == 3)
		{
			date2.year = date2.normalizeYear(y);
			date2.month = m;
			date2.day = dy;
			//如果确实是提取到三个整数,成功进入if循环,如果赋值中发现整数非法,恢复默认值
			if (!date2.isValidDate()) 
			{
				date2.year = 1949;
				date2.month = 10;
				date2.day = 1;
			}
		}
		return in;
	}
	//关系运算符 返回值必须是bool,关系运算符的结果只有真假且作为成员函数只有一个形参
	bool operator==(const Date& other)const
	{
		return this->year == other.year && this->month == other.month && this->day == other.day;
	}
	bool operator!=(const Date& other)const
	{
		//其中==是基于已经实现好的"=="来实现比较的
		return !(*this == other);
	}
	bool operator<(const Date& other)const
	{
		//不是不相等就要返回other大于this的,是判断这样的结果是true还是false
		if (this->year != other.year)
		{
			return this->year < other.year;
		}
		if (this->month != other.month)
		{
			return this->month < other.month;
		}
		return this->day < other.day;
	}
	bool operator<=(const Date& other)const
	{
		//其中< == 是基于已经实现好的代码来进行比较的
		return *this < other || *this == other;
	}
	bool operator>(const Date& other)const
	{
		// !<= 反过来就是this > other
		return !(*this <= other);
	}
	bool operator>=(const Date& other)const
	{
		//!< 反过来就是this >= other
		return !(*this < other);
	}
	//++,--,+=,-+
	//前置++
	Date& operator++()
	{
		this->day++;
		//检验是否因为+1天而产生月份/年份增加
		adjustDatr();
		return *this;
	}
	//后置++
	Date operator++(int)
	{
		//拷贝
		Date temp = *this;
		//基于已实现的++来处理
		++(*this);
		return temp;
	}
	//前置--
	Date& operator--()
	{
		this->day--;
		adjustDatr();
		return *this;
	}
	//后置--
	Date operator--(int)
	{
		Date temp = *this;
		--(*this);
		return temp;
	}
	//日期+天数
	Date operator+(int days)const
	{
		Date d = *this;
		d.day += days;
		d.adjustDatr();
		return d;
	}
	//日期 - 天数
	Date operator-(int days)const
	{
		Date d = *this;
		d.day -= days;
		d.adjustDatr();
		return d;
	}
	//日期+=天数
	Date operator+=(int days)
	{
		*this = *this + days;
		return *this;
	}
	//日期 -= 天数
	Date operator-=(int days)
	{
		*this = *this - days;
		return *this;
	}
	//两日期相减,差->天数
	int toTotalDays(const Date& d)const
	{
		int total = 0;
		//累加之前所有年份的天数
		for (int y = 1; y < d.year; y++)
		{
			if ((year%4 == 0 && year%100 != 0) || (year%400 == 0))
			{
				total += 366;
			}
			else
			{
				total += 365;
			}
		}
		//累加当年的之前月份的天数
		for (int m = 1; m < d.month; m++)
		{
			//创建一个临时Date对象,用于调用getDaysOfMonth
			Date temp(d.year, m, 1);
			total += temp.getDaysOfMonth();
		}
		//累加当月天数
		total += d.day;
		return total;
	}
	int operator-(const Date& date)const
	{
		return toTotalDays(*this) - toTotalDays(date);
	}
	//析构函数
	~Date() = default;

};
int main()
{
	//【第一问】
	//默认输出日期
	Date d1;
	cout << "默认日期:" << d1 << endl;

	////自定义日期
	Date d2(2026, 2, 19);
	cout << "自定义日期:" << d2 << endl;

	////两位数年份
	Date d3(26, 2, 19);
	cout << "补充四位数年份:" << d3 << endl;

	////非法日期恢复默认日期
	Date d4(-1, 2, 19);
	cout << "非法日期恢复默认值" << d4 << endl;

	//【第二问】
	Date d5;
	cout << "请输入日期(格式:年.月.日,支持2 / 4位年、1 / 2位月日):";
	cin >> d5;
	cout << "你输入的日期解析后:" << d5 << endl;

	//【第三问】
	//在第一第二问实现时候顺带实现了
	//就是通过friend ostream& operator<<(ostream& out, const Date& date)实现

	//【第四问】
	//关系运算符
	// 太多例子了都是一样的,就实现一个比较符,其他的都一样
	Date d6(2026, 2, 19);
	Date d7(2025, 5, 5);
	if (d6 < d7)
	{
		cout << "d6  < d7" << endl;
	}
	else {
		cout << "d6 > d7" << endl;
	}

	//【第五问】
	Date d8(2026, 12, 31);
	cout << d8++ << endl;
	cout << d8 << endl;
	// -- 如出一辙
	// += -=
	Date d9(2026, 2, 23);
	d9.operator+=(10);
	cout << d9;
	d9.operator-=(3);
	cout << d9;

	//【第六问】
	Date d10(2026, 2, 23);
	Date d11(2025, 10, 10);
	int result = d10 - d11;
	cout << "两日期相减天数差为:" << result << endl;

	return 0;
}

其中main函数中的检验,需要读者一问一问的去检验,需要注销其他问的再运行,避免报错

相关推荐
Lsir10110_2 小时前
【Linux】生产者-消费者模型及条件变量
linux·运维·开发语言·c++
仰泳的熊猫2 小时前
题目1549:蓝桥杯算法提高VIP-盾神与积木游戏
数据结构·c++·算法·蓝桥杯
tod1132 小时前
C++核心知识点全解析(三)
开发语言·c++·面试经验
WW_千谷山4_sch2 小时前
MYOJ_11705:(洛谷P1137)旅行计划(经典拓扑排序)
c++·算法·动态规划·图论
FMRbpm2 小时前
string课后练习
c++·算法·新手入门
yyuan_in2 小时前
【已解决】VisualStudio写中文报错的解决办法
c++·visual studio
郝学胜-神的一滴2 小时前
高并发服务器开发:多进程与多线程实现深度解析
linux·服务器·开发语言·c++·程序人生
特种加菲猫2 小时前
C++对象模型与内存管理深度解析:从构造、友元到拷贝优化
开发语言·c++