【C/C++实战项目】日期类设计

目录

一、设计思路

二、Date类的封装:Date.hpp

三、测试文件:main.cc


一、设计思路

Date类的功能:

  • Date类的赋值构造、拷贝构造
  • Date日期的比较(==、!=、>、>=、<、<=)
  • 计算Date日期与天数相加减得到的新日期
  • Date日期的前置与后置自增自减
  • Date日期与Date日期间相差的天数计算
  • 查询当前Date日期是星期几

算法设计:

  • 熟悉日期的基本性质,闰年的判断、每个月对应的天数
  • 根据日期的性质可以计算出某个日期的总天数,根据某个日期的总天数可以得到某个日期是星期几
  • 运算符重载,==、!=、>、>=、<、<= 这些运算符,只需要实现其中的部分,其他的可以利用已经重载过的运算符函数实现自身功能,+=、+、-=、-、++、--也是同理
  • 公元 1 年 1 月 1 日默认是 周一,所以得到某个日期与公元 1 / 1 /1 的天数差值,就可以计算出周几

总结:本项目比较代码较简单,主要涉及类的构造与运算符重载,重点的算法设计是运算符重载的复用。

二、Date类的封装:Date.hpp

#define _CRT_SECURE_NO_WARNINGS 1

#pragma once

#include <iostream>
#include <cassert>
#include <string>

class Time
{
public:
	Time(int h = 0, int m = 0, int s = 0)
		: _h(h), _m(m), _s(s)
	{
		assert(_h >= 0 && _m >= 0 && _s >= 0);
		assert(_h < 24 && _m < 60 && _s < 60);
	}

	Time(const Time& time)
	{
		_h = time._h;
		_m = time._m;
		_s = time._s;
	}

	Time& operator=(const Time& time)
	{
		_h = time._h;
		_m = time._m;
		_s = time._s;
		return *this;
	}

private:
	int _h, _m, _s;
};

class Date
{
public:
	// 构造
	Date(int year = 1, int mon = 1, int day = 1, Time time = Time())
		: _year(year), _mon(mon), _day(day), _time(time)
	{
		assert(_year >= 1 && _mon >= 1 && _day >= 1);
		assert(_mon <= 12 && _day <= Get_Mon_Days(_year, _mon));
	}

	Date(const Date& date)
	{
		_year = date._year;
		_mon = date._mon;
		_day = date._day;
		_time = date._time;
	}

	Date& operator=(Date Date)
	{
		Swap(Date);
		return *this;
	}

	// 日期类比较
	bool operator==(const Date& Date)
	{
		if (_year == Date._year && _mon == Date._mon && _day == Date._day)
			return true;
		return false;
	}

	bool operator!=(const Date& Date)
	{
		return !(*this == Date);
	}

	bool operator>(const Date& Date)
	{
		if ((_year > Date._year) ||
			(_year == Date._year && _mon > Date._mon) ||
			(_year == Date._year && _mon == Date._mon && _day > Date._day))
			return true;
		return false;
	}

	bool operator>=(const Date& Date)
	{
		return (*this > Date || *this == Date);
	}

	bool operator<(const Date& Date)
	{
		return !(*this >= Date);
	}

	bool operator<=(const Date& Date)
	{
		return (*this < Date || *this == Date);
	}

	// 日期 ± 天数 = 日期
	Date& operator+=(int days)
	{
		if (days < 0)
		{
			*this -= -days;
			return *this;
		}
		_day += days;
		while (_day > Get_Mon_Days(_year, _mon))
		{
			_day -= Get_Mon_Days(_year, _mon);
			++_mon;
			if (_mon == 13)
			{
				_mon = 1;
				++_year;
			}
		}
		return *this;
	}

	Date operator+(int days)
	{
		Date tmp(*this);
		tmp += days;
		return tmp;
	}

	Date& operator-=(int days)
	{
		if (days < 0)
		{
			*this += -days;
			return *this;
		}
		_day -= days;
		while (_day < 1)
		{
			--_mon;
			if (_mon == 0)
			{
				_mon = 12;
				--_year;
			}
			_day += Get_Mon_Days(_year, _mon);
		}
		return *this;
	}

	Date operator-(int days)
	{
		Date tmp(*this);
		tmp -= days;
		return tmp;
	}

	// 日期自增自减
	Date& operator++()
	{
		return *this += 1;
	}

	Date operator++(int)
	{
		Date tmp(*this);
		*this += 1;
		return tmp;
	}

	Date& operator--()
	{
		return *this -= 1;
	}

	Date operator--(int)
	{
		Date tmp(*this);
		*this -= 1;
		return tmp;
	}

	// 日期 - 日期 = 天数
	int operator-(const Date& date)
	{
		int flag = 1;
		Date max(*this);
		Date min(date);
		if (*this < date)
		{
			max = date;
			min = *this;
			flag = -1;
		}
		int n = 0;
		while (min != max)
		{
			++min;
			++n;
		}
		return flag * n;
	}

	// 获取当期日期的总天数
	int Get_Date_days()
	{
		int days = 0;
		for (int i = 1; i < _year; ++i)
		{
			if (Leap_Year(i))
				days += 366;
			else
				days += 365;
		}
		for (int i = 1; i < _mon; ++i)
		{
			days += Get_Mon_Days(_year, i);
		}
		days += _day;
		return days;
	}

	// 查询当前日期对应的星期
	std::string Search_Week()
	{
		int days = Get_Date_days();
		int pos = days % 7;
		std::string week[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
		return week[pos];
	}

	// 输入输出,友元函数
	friend std::ostream& operator<<(std::ostream& os, const Date& date);
	friend std::istream& operator>>(std::istream& is, Date& date);

	void Print()
	{
		printf("%04d-%02d-%02d %s\n", _year, _mon, _day, Search_Week().c_str());
	}

private:
	bool Leap_Year(int year)
	{
		if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
			return true;
		return false;
	}

	int Get_Mon_Days(int year, int mon)
	{
		int month_days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (mon == 2 && Leap_Year(year))
			return 29;
		return month_days[mon];
	}

	void Swap(Date& Date)
	{
		std::swap(_year, Date._year);
		std::swap(_mon, Date._mon);
		std::swap(_day, Date._day);
		std::swap(_time, Date._time);
	}

private:
	int _year, _mon, _day;
	Time _time;
};

inline std::ostream& operator<<(std::ostream& os, const Date& date)
{
	os << date._year << "-" << date._mon << "-" << date._day;
	return os;
}

inline std::istream& operator>>(std::istream& is, Date& date)
{
	is >> date._year >> date._mon >> date._day;
	return is;
}

三、测试文件:main.cc

#define _CRT_SECURE_NO_WARNINGS 1

#include "Date.hpp"
using namespace std;

void Test1()
{
	Date d1;
	Date d2(2023, 8, 4);
	Date d3(d2);
	cout << "d1: " << d1 << endl;
	cout << "d2: " << d2 << endl;
	cout << "d3: " << d3 << endl;
	cout << "d2.operator==(d1): " << d2.operator==(d1) << endl;
	cout << "d2 != d1: " << (d2 != d1) << endl;
	cout << "d2 == d3: " << (d2 == d3) << endl;
	cout << "(d2 += 100) > d3: " << ((d2 + 100) > d3) << endl;
	cout << "d2 > (d3 + 100): " << (d2 > (d3 + 100)) << endl;
	cout << "d2 >= (d3 + 100 - 100): " << (d2 >= (d3 + 100 - 100)) << endl;
	cout << endl;
}

void Test2()
{
	Date d(2023, 8, 5);
	(d + 100).Print();
	(d + 1000).Print();
	(d + 10000).Print();
	(d + 100000).Print();
	Date ret1(d + 100000);
	cout << "ret1: " << ret1 << endl;
	(d++).Print();
	(++d).Print();

	cout << endl;
	(d--).Print();
	(--d).Print();
	(d - 100).Print();
	(d - 1000).Print();
	(d - 10000).Print();
	(d - 100000).Print();
	Date ret2(d - 100000);
	cout << "ret2: " << ret2 << endl;
	cout << "ret - ret2: " << (ret1 - ret2) << endl;
	cout << endl;
}

void Test3()
{
	cout << "*********************************" << endl;
	cout << "*                               *" << endl;
	cout << "*     1. 日期加减天数           *" << endl;
	cout << "*     2. 日期减去日期           *" << endl;
	cout << "*     3. 查询日期星期           *" << endl;
	cout << "*     0. 退出                   *" << endl;
	cout << "*                               *" << endl;
	cout << "*********************************" << endl;
	int option;
	do
	{
		cout << "请输入选项: ";
		cin >> option;
		if (option == 1)
		{
			Date d;
			cout << "请输入日期: ";
			cin >> d;
			int days = 0;
			cout << "请输入天数: ";
			cin >> days;
			(d + days).Print();
			cout << endl;
		}
		else if (option == 2)
		{
			Date d1, d2;
			cout << "请输入日期1: ";
			cin >> d1;
			cout << "请输入日期2: ";
			cin >> d2;
			cout << (d1 - d2) << endl << endl;
		}
		else if (option == 3)
		{
			Date d;
			cout << "请输入日期: ";
			cin >> d;
			cout << d.Search_Week() << endl << endl;
		}
		else if (option == 0)
		{
			cout << "退出程序" << endl;
		}
		else
		{
			cout << "输入错误,请重新选择" << endl;
			char buffer[1024];
			fgets(buffer, sizeof(buffer), stdout);
		}
	} while (option);
}

int main()
{
	//Test1();	// 测试构造与比较
	//Test2();	// 测试日期运算
	Test3();

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllinTome

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值