c++中 Date(年月日)类的各种操作实现

这篇博客展示了如何用C++编写一个日期类,包括月份天数计算、日期增减、比较等操作。通过友元函数重载了输入输出流操作符,实现了日期的易读易写。同时,博客中包含了一系列的日期操作示例,如日期的加减、比较等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

练习写了一个日期类的操作,虽然个别函数的方法可能不是很好,但结果还行吧。

#include<iostream>
#include<string.h>
#include<stdio.h>

using namespace std;

class Date
{
	friend ostream& operator<<(ostream& out, Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	bool Is_leap_year() {
		return((m_year % 4 == 0 && m_year % 100 != 0) || m_year % 400 == 0);
	}
	// 获取某年某月的天数
	int GetMonthDay(int year, int month)
	{
		int day = days[month];
		if(Is_leap_year() &&  month==2)
		{
			day += 1;
		}
		return day;
	}

	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1) {
		m_year = year;
		m_month = month;
		m_day = day;
	}

	// 拷贝构造函数
	// d2(d1)
	Date (const Date& d) {	
			m_year = d.m_year;
			m_month = d.m_month;
			m_day = d.m_day;
	}

	// 赋值运算符重载
	// d2 = d3 -> d2.operator=(&d2, d3)
	Date& operator=(const Date& d) {
		if (this != &d) {
			m_year = d.m_year;
			m_month = d.m_month;
			m_day = d.m_day;
		}
		return *this;
	}
	// 析构函数
	~Date() {

	}

	// 前置++
	Date& operator++() {
		m_day++;
		if (m_day > GetMonthDay(m_year, m_month)) {
			m_month++;
			m_day = 1;
		}
		if (m_month > 12) {
			m_month = 1;
			m_year++;
		}
		return *this;
	}
	// 后置++
	Date operator++(int) {
		Date tmp = *this;
		++* this;
		return tmp;
	}
	// 后置--
	Date operator--(int) {
		Date tmp = *this;
		--* this;
		return tmp;
	}
	// 前置--
	Date& operator--() {
		m_day--;
		if (m_day <=0) {
			m_month--;
			if (m_month <= 0) {
				m_year--;
				m_month = 12;
			}
			m_day = GetMonthDay(m_year, m_month);
		}	
		return *this;
	}
	// >运算符重载
	bool operator>(const Date& d) {
		return (m_year > d.m_year)
			|| (m_year == d.m_year  &&  m_month > d.m_month)
			|| (m_year == d.m_year  &&  m_month == d.m_month  &&  m_day > d.m_day);
	}
	// ==运算符重载
	bool operator==(const Date& d) {
		return (m_year==d.m_year &&  m_month==d.m_month  &&  m_day==d.m_day);
	}
	// >=运算符重载
	inline bool operator >= (const Date& d) {
		return !(*this < d);
	}
	// <运算符重载
	bool operator < (const Date& d) {
	return (m_year < d.m_year)
			|| (m_year == d.m_year && m_month < d.m_month)
			|| (m_year == d.m_year && m_month == d.m_month && m_day < d.m_day);
	}
	// <=运算符重载
	bool operator <= (const Date& d) {
		return !(*this > d);
	}
	// !=运算符重载
	bool operator != (const Date& d) {
		return !(m_year == d.m_year && m_month == d.m_month && m_day ==d.m_day);
	}

	//根据年月日判断这是这一年的第几天
	int GetDayByYMD(int year, int month, int day)
	{
		int days = 0;
		for (int i = 1; i < month; ++i)
		{
			days += GetMonthDay(year, i);
		}
		days += day;
		return days;
	}

	// 日期+=天数
	Date& operator+=(int day) {
		day += m_day;
		m_day = 0;
		while (day > GetMonthDay(m_year,m_month)){
			day -= GetMonthDay(m_year, m_month);
			if (++m_month == 13) {
				m_month = 1;
				m_year++;
			}
		}
		m_day += day;
		return *this;
	}
	// 日期+天数
	Date operator+(int day) {
		Date tmp = *this;
		tmp += day;
		return tmp;
	}
	// 日期-天数
	Date operator-(int day) {
		Date tmp = *this;
		tmp -= day;
		return tmp;
	}
	// 日期-=天数
	Date& operator-=(int day) {

		while (day > m_day) {
			day -= m_day;
			m_month--;
			if (m_month == 0) {
				m_month = 12;
				m_year--;
			}
			m_day = GetMonthDay(m_year, m_month);	
		}	

		m_day -= day;
		if (m_day == 0) {
			m_month = (m_month - 1);
			if (m_month == 0){
				m_month = 12;
				m_year--;
			}
			m_day = GetMonthDay(m_year, m_month);
		}
		return *this;
	}
	// 日期-日期 返回天数
	int operator-(const Date& d) {	
		int count = 0;
		Date tmp;
		if (*this >=d){
			tmp = d;
			while (!(m_year == tmp.m_year && m_month == tmp.m_month && m_day == tmp.m_day)) {
				tmp++;
				count++;
			}
		}
		else {
			tmp = *this;
			while (!(tmp.m_year == d.m_year && tmp.m_month == d.m_month && tmp.m_day == d.m_day)) {
				tmp++;
				count++;
			}
			count= -count;
		}	
		return count;
	}


private:
	int m_year;
	int m_month;
	int m_day;
};

//这里对该类的输入输出操作进行了运算符重载,方便使用;
ostream& operator<<(ostream& out, Date& d) {
	out << d.m_year << "年" << d.m_month << "月" << d.m_day<<"日";
	return out;
}
istream& operator>>(istream& in, Date& d) {
	in>>d.m_year >> d.m_month >>d.m_day  ;
	return in;
}

int  main()
{
	Date d1(2020,12,31);
	Date d2(2020, 11, 30);
	Date d3(2020, 6, 1);
	Date d4 = d3;
	Date d5= d2 + 1000;
	Date d6 (d5);
	d6-= 1000;
	cout << d1 << endl;
	cout << d2 << endl;
	cout <<d3 << endl;
	cout << d4 << endl;
	cout << d5 << endl;
	cout << d6 << endl;
	cout << d2-d3<< endl;
	if (d3==d4 && d1>d2 && d5>=d2&& d3<d2 && d1!=d2  ) {
		cout << "true" << endl;
	}
	return 0;
}

部分操作运行结果

<think>好的,我现在需要帮助用户创建一个名为Date的日期,包含年、月、日作为成员变量。用户的问题看起来是关于面向对象编程的,可能是在学习Java或者似的编程语言。根据用户提供的引用,特别是引用[1]提到了设计Date,成员函数实现设置和输出日期,这可能涉及到的结构、构造方法、访问器方法(getter和setter)以及可能的其他方法,比如输出日期格式。 首先,我要确定用户使用的编程语言。引用[1]没有明确说明,但引用[4]提到了Java,而示例中的代码是Python。不过用户的问题可能更偏向于Java,因为引用[1]中的设计通常更符合Java的语法,比如私有成员变量和公有方法。但用户也可能需要其他语言的实现,比如Python。不过用户的问题里提到“成员变量”,这通常更常见于Java或C++,而Python中使用属性(attributes)。需要进一步确认,但根据示例中的Python代码,用户可能接受不同语言的例子。 不过,用户的问题明确说“创建一个名为date的日期”,而引用的示例中引用了Java相关的设计。所以可能需要提供Java的实现。但为了覆盖可能性,可能需要给出两种语言的示例?或者询问用户需要哪种语言?不过用户的问题没有说明,可能需要默认选择一种,比如Java,因为引用[1]中的描述更接近Java的结构。 接下来,分析需求:Date,年、月、日为成员变量。需要考虑以下几点: 1. 成员变量的访问权限:通常私有(private),通过公共方法访问和修改。 2. 构造方法:无参构造和有参构造,用于初始化年月日。 3. 访问器方法(getter)和修改器方法(setter)。 4. 可能的有效性检查,比如月份是否在1-12之间,日期是否合理。 5. 输出方法,比如toString(),用于显示日期。 根据引用[1],需要设置和输出日期,所以需要set方法和输出方法,比如printDate()或者覆盖toString()。 另外,引用[3]提到了构造方法,默认值和无参构造,这里可能也需要为Date提供默认构造方法,比如设置为某个默认日期,如2024年1月1日,或者让无参构造调用有参构造并传递默认值。 步骤: 1. 定义Date,私有成员变量year, month, day。 2. 编构造方法:无参构造和有参构造。 3. 编getter和setter方法,确保在set时进行有效性检查。 4. 编输出日期的方法,比如toString()。 5. 考虑异常处理,比如无效的月份或日期,是否需要抛出异常或者静默处理?通常应该在setter中进行验证,如果无效则抛出IllegalArgumentException,或者在构造方法中检查。 例如,在Java中,Date的结构可能如下: public class Date { private int year; private int month; private int day; // 无参构造,使用默认值 public Date() { this(2024, 1, 1); // 默认日期 } // 有参构造 public Date(int year, int month, int day) { setYear(year); setMonth(month); setDay(day); } // getters and setters public int getYear() { return year; } public void setYear(int year) { if (year < 0) { throw new IllegalArgumentException("年份不能为负数"); } this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { if (month < 1 || month > 12) { throw new IllegalArgumentException("月份必须在1-12之间"); } this.month = month; } public int getDay() { return day; } public void setDay(int day) { // 需要检查月份对应的天数,比如2月是否有28或29天,这里可能需要更复杂的逻辑 // 暂时简化处理,假设每个月最多31天 if (day < 1 || day > 31) { throw new IllegalArgumentException("日期无效"); } this.day = day; } @Override public String toString() { return String.format("%04d-%02d-%02d", year, month, day); } } 但这里的天数检查并不准确,因为不同的月份天数不同,比如4月有30天,2月可能有28或29天。用户可能希望有更精确的验证。因此,需要考虑更复杂的逻辑,比如根据月份和年份判断天数是否正确。 例如,可以添加一个方法isValidDate(),在设置day时调用。或者在setDay方法中检查月份和年份,然后判断天数是否合理。 这可能比较复杂,但用户的问题可能只需要基础的结构,而详细的验证可能需要更多代码。所以可能需要提示用户这部分需要进一步处理。 另外,用户可能希望示例代码,所以需要确保代码语法正确。 另外,在引用[1]中提到的成员函数实现日期的设置和输出,因此需要setDate()方法和printDate()方法,或者通过setter和toString()的组合。 综上,Java中的Date应该包含私有成员变量、构造方法、getter和setter,以及toString方法。而有效性检查是重要的部分,但可能需要用户自己进一步处理复杂的逻辑,比如闰年判断。 如果用户使用Python,代码会更简单,因为不需要显式的getter和setter,但可以按需添加。例如: class Date: def __init__(self, year=2024, month=1, day=1): self.year = year self.month = month self.day = day def set_year(self, year): if year < 0: raise ValueError("年份不能为负数") self.year = year def set_month(self, month): if month < 1 or month > 12: raise ValueError("月份必须在1-12之间") self.month = month def set_day(self, day): # 同样需要更复杂的天数检查 if day < 1 or day > 31: raise ValueError("日期无效") self.day = day def __str__(self): return f"{self.year}-{self.month:02d}-{self.day:02d}" 但用户的问题可能更偏向Java,因为引用[1]中的描述似Java设计。因此,可能需要以Java为例。 总结,回答应该包括: - 的定义,私有成员变量。 - 构造方法(默认和带参数)。 - Getter和Setter方法,带有基本验证。 - toString方法输出日期。 - 提示更复杂的验证需要额外处理。 同时,生成相关问题,如有效性检查、不同语言实现、应用场景等。</think>### 如何创建包含年、月、日的日期 在编程中定义一个日期`Date`,需要包含年、月、日作为成员变量,并提供基本操作。以下是Java语言的实现示例: #### 1. 定义结构 ```java public class Date { // 私有成员变量 private int year; private int month; private int day; // 无参构造方法(默认日期:2024年1月1日) public Date() { this(2024, 1, 1); } // 有参构造方法 public Date(int year, int month, int day) { setYear(year); setMonth(month); setDay(day); } // Getter和Setter方法 public int getYear() { return year; } public void setYear(int year) { if (year < 0) throw new IllegalArgumentException("年份不能为负数"); this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { if (month < 1 || month > 12) throw new IllegalArgumentException("月份必须在1-12之间"); this.month = month; } public int getDay() { return day; } public void setDay(int day) { // 简化天数验证(需根据具体月份和闰年完善) if (day < 1 || day > 31) throw new IllegalArgumentException("日期无效"); this.day = day; } // 输出日期字符串 @Override public String toString() { return String.format("%04d-%02d-%02d", year, month, day); } } ``` #### 2. 关键功能说明 - **构造方法**:支持默认日期(2024-01-01)和自定义日期初始化[^1]。 - **数据验证**:在`setMonth`和`setDay`方法中进行了基础验证(需补充闰年和月份天数逻辑)[^3]。 - **输出格式化**:通过`toString`方法返回`YYYY-MM-DD`格式的日期字符串。 #### 3. 使用示例 ```java public class Main { public static void main(String[] args) { Date defaultDate = new Date(); // 默认日期 Date customDate = new Date(2023, 12, 25); // 自定义日期 System.out.println(defaultDate); // 输出:2024-01-01 System.out.println(customDate); // 输出:2023-12-25 } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值