【C++】用C++实现一个日期计算器

欢迎来到CILMY23的博客

本篇主题为: 用C++实现一个日期计算器

个人主页:CILMY23-CSDN博客

系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux

感谢观看,支持的可以给个一键三连,点赞关注+收藏。


写在前头:

知识所需:构造函数,运算符重载,类和对象,类的声明和定义分离,内联函数,拷贝构造

额外知识: 友元声明

文件: Date.h Date.cpp test.cpp

注意:日期类的拷贝构造和析构都是不需要写的


目录

一、功能逻辑图

二、Date.cpp代码实现 

2.1 日期比较  

2.2 日期加天数 

2.3 日期减天数 

2.4 日期前置++和后置++

2.5 日期前置--和后置--

2.6 日期与日期相差的天数

2.7 日期显示 

2.8 流输出

2.9 流提取

2.10 日期类输入的检查和日期的初始化

三、Date.h中的声明 


一、功能逻辑图

日期计算器的功能如下,我们要考虑日期的增加和减少,自增和自减,以及两个日期类的比较,以及当前日期类的日期显示和用户的输入输出。

二、Date.cpp代码实现 

2.1 日期比较  

日期比较主要实现以下六种比较,因为日期的比较是自定义类型,所以我们需要用到运算符重载来进行比较,先通过实现等于和小于,其余的功能复用就可以了。 

 代码如下:

//日期比较
//小于
bool Date::operator<(const Date& d)
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month < d._month)
		{
			return true;
		}
		else if (_month == d._month)
		{
			if (_day < d._day)
			{
				return _day < d._day;
			}
		}
	}
	return false;
}
//小于等于
bool Date::operator<=(const Date& d)
{
	return (*this < d) || (*this == d);
}
//大于
bool Date::operator>(const Date& d)
{
	return !((*this < d) || (*this == d));
}
//大于等于
bool Date::operator>=(const Date& d)
{
	return !(*this < d);
}
//等于
bool Date::operator==(const Date& d)
{
	return _year == d._year &&
		_month == d._month
		&& _day == d._day;
}
//不等于
bool Date::operator!=(const Date& d)
{
	return !(*this == d);
}

2.2 日期加天数 

日期增加天数我们所用到的运算符是 + 和 +=,日期增加有两种方式,一种是+复用+=,一种是+=复用+,我们实现的是+复用+=,另外一种会创建新对象造成效率降低。

Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year += 1;
		}
	}
	return *this;
}
Date Date::operator+(int day)
{
	Date tmp = *this;//拷贝构造
	tmp += day;
	return tmp;
}

2.3 日期减天数 

日期减去天数也同理日期增加天数,先实现 -= 然后再去实现 - 

Date& Date::operator-=(int days) 
{
	_day -= days;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0) 
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}
Date Date::operator-(int days)
{
	Date tmp = *this;
	tmp -= days;
	return tmp;
}

2.4 日期前置++和后置++

日期前置++和后置++ 主要区别在于,C++中用一个形参类型区分前置和后置。在编译器传参的时候会传一个整型,然后表示这是一个后置++。 

//日期自增
//前置++
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
//后置++
Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;
	return tmp;
}

2.5 日期前置--和后置--

日期的前置--和后置--也同理日期的前置++和后置++。 

//日期自减少
//前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
//后置--
Date Date::operator--(int)
{
	Date tmp = *this;
	*this -= 1;
	return tmp;
}

2.6 日期与日期相差的天数

日期与日期的相减,是运算符 - 的重载函数。 主要思路是,通过把最小的日期自增到最大的日期,计算次数就是它们之间相差的天数。

//日期与日期的相减
int Date::operator-(const Date& d)
{
	int flag = -1;
	int n = 0;
	Date min = d;
	Date max = *this;
	if (*this < d)
	{
		flag = 1;
		min = *this;
		max = d;
	}
	while (min != max)
	{
		++min;
		++n;
	}
	return flag * n;
}

2.7 日期显示 

当前日期显示则较为容易,主要是让用户知道自己输入的两个日期是什么样的。

void Date::Print()
{
	cout << "当前日期:" << _year << "/" << _month << "/" << _day << endl;
}

2.8 流输出

流输出主要是方便我们对日期类的输出,用上流运算符方便打印。 

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "天" << endl;
	return out;
}

2.9 流提取

 流提取也同理流输出。但是注意在对日期的输入前,需要我们对日期进行检查。

istream& operator>>(istream& in, Date& d)
{
	
	while (1)
	{
		cout << "请输入对应的年月日" << endl;
		in >> d._year
			>> d._month
			>> d._day;
		if (!d.CheckInvalid())
		{
			cout << "日期输入错误,请重新输入" << endl;
		}
		else
		{
			break;
		}
	}
	return in;
}

2.10 日期类输入的检查和日期的初始化

 日期类的检查:

//日期检查
bool Date::CheckInvalid()
{
	if (_year <= 0
		|| _month < 1 || _month >12
		|| _day < 1 || _day > GetMonthDay(_year, _month))
	{
		return false;
	}
	else
		return true;
}

日期类的初始化:

//日期初始化
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
	if (!CheckInvalid())
	{
		cout << "构造日期非法" << endl;
	}
}

三、Date.h中的声明 

代码如下: 

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
//日期计算器的声明
#include#include
using namespace std;
class Date
{
public:
	//日期初始化
	//全缺省构造函数
	//声明给缺省值,定义不给缺省值
	Date(int year = 1, int month = 1, int day = 1);
	//日期比较
	bool operator<(const Date& d);
	bool operator<=(const Date& d);
	bool operator>(const Date& d);
	bool operator>=(const Date& d);
	bool operator==(const Date& d);
	bool operator!=(const Date& d);
	//日期增加天数
	Date& operator+=(int day);
	Date operator+(int day);
	//inline 不写:本质就是内联,不声明和定义分离
	int GetMonthDay(int year, int month)
	{
		assert(month > 0 && month < 13);
		static int MonthDay[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			return 29;
		}
		return MonthDay[month];
	}
	//日期减少
	Date& operator-=(int day);
	Date operator-(int day);
	//日期自增
	//前置++
	Date& operator++();
	//后置++
	Date operator++(int);
	//日期自减
	//前置--
	Date& operator--();
	//后置++
	Date operator--(int);
	//日期与日期的相减
	int operator-(const Date& d);
	//用户输出
	friend ostream& operator<<(ostream& out, const Date& d);
	//用户输入
	friend istream& operator>>(istream& in, Date& d);
	//日期检查
	bool CheckInvalid();
	//日期打印
	void Print();
private:
	int _year;
	int _month;
	int _day;
};
//用户输出
ostream& operator<<(ostream& out,const Date& d);
//用户输入
istream& operator>>(istream& in, Date& d);

后文: 

日期计算器的大致功能如上,主要还是对运算符重载的应用和之前类和对象的知识掌握。有很多地方也不够完善,当然还有很多地方需要改进,在实际应用中还需要调用以上的接口,那日期计算器的界面我也写了一点,大家可以尽情发挥。

//日期界面
//显示日期计算器界面
void CalculatorInterface()
{
	int n = 1;
	cout << "欢迎使用日期计算器!" << endl;
	cout << "请选择您想要执行的操作:" << endl;
	cout << "1. 计算两个日期之间的天数差" << endl;
	cout << "2. 计算某个日期之后或之前的日期" << endl;
	cout << "0. 退出" << endl;
	cout << "请输入选项数字: ";
	cin >> n;
	if (n == 0)
	{
		exit(1);
	}
	else if(n == 1)
	{
		//....
	}
	else
	{
		cout << "无效的选项,请重新输入。" << endl;
	}
}

为了简便,也可以使用转移表,或者使用switch case 来进行选择对应的功能…… 


 感谢各位同伴的支持,本期日期计算器篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。