C++第四篇 一篇文章学完C++所有的日期类函数

目录

1.data.h文件

1.1已知年月获取天数函数 int getday(int year, int month) const

2.函数的实现

2.1构造函数

2.2检查日期合法函数

2.3日期类重载小于号(<)

2.4日期类重载等于号(==)

2.5日期类重载小于等于号(<=)

2.6日期类重载大于号(>)

2.7重载大于等于号(>=)

2.8重载不等于号(!=)

2.9重载加等于号(+=)

2.10重载减等于号(-=)

2.11重载加号(+)(日期+天数)

2.12重载减号(-)(日期-天数)

2.13重载后置加加(后置++)

2.14重载前置加加(++前置)

2.15重载后置减减(后置--)

2.16重载前置减减(--前置)

2.17重载减号(-)(日期-日期)

2.18重载<<号

2.19重载>>号

2.10 data.cpp源码


        主要实现了对日期的操作,包括日期的比较,日期-日期,日期+天数,日期++,++日期,日期,--日期,以及对日期中>> 和 << 的重载。

1.data.h文件

采用了声明与定义分离。

#pragma once
#include<iostream>
#include<algorithm>
#include<assert.h>

using namespace std;

class Data {
	//友元函数声明
	friend ostream& operator<<(ostream& out, const Data& d);
	friend istream& operator>>(istream& in, Data& d);
public:

	Data(int year = 1900, int month = 1, int day = 1);//构造函数
	bool CheckDate()const;
	void Print()const;

	int getday(int year, int month) const
	{
		assert(month > 0 && month < 13);
		static int monthDayArray[13] = { -1, 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 monthDayArray[month];
	}

	bool operator<(const Data& d) const;
	bool operator<=(const Data& d) const;
	bool operator>(const Data& d) const;
	bool operator>=(const Data& d) const;
	bool operator==(const Data& d) const;
	bool operator!=(const Data& d) const;
	Data operator+(int day) const;
	Data& operator+=(int day);
	Data operator-(int day) const;
	Data& operator-=(int day);
	Data operator++(int);
	Data& operator++();
	Data operator--(int);
	Data& operator--();
	int operator-(const Data& d) const;

private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, const Data& d);
istream& operator>>(istream& in, Data& d);

1.1已知年月获取天数函数 int getday(int year, int month) const

int getday(int year, int month) const
	{
		assert(month > 0 && month < 13);
		static int monthDayArray[13] = { -1, 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 monthDayArray[month];
	}

(1).我们直接将数组下标1到12设置为每月的天数,特判当时2月且时闰年时,我们返回29即可。

2.函数的实现

2.1构造函数

Data::Data(int year, int month, int day) {
	_year = year;
	_month = month;
	_day = day;
	if (!CheckDate())
	{
		cout << "非法日期:";
		Print();
	}
}

(1).简单的构造函数的实现,要判断一下当前日期是否合法。

2.2检查日期合法函数

bool Data::CheckDate()const
{
	if (_month <= 0 || _month > 12 || _day<1 || _day>getday(_year, _month)) {
		return false;
	}
	return true;
}

(1).当月小于等于0,或者月大于12,或者天小于1,或者天大于该月的总天数,则返回fallse,其余情况返回true。

2.3日期类重载小于号(<)

bool Data::operator<(const Data& d) const
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month < d._month)
		{
			return true;
		}
		else if (_month == d._month)
		{
			return _day < d._day;
		}
	}
	return false;
}

(1).先判断年,若年小于则返回true即可,如果等于时,在判断月,如果月小于,则返回true,若月等于时,则判断天,直接判断 _day < d._day 是否成立即可。最后返回false。

2.4日期类重载等于号(==)

bool Data::operator==(const Data& d) const
{
	return _year == d._year && _month == d._month && _day == d._day;
}

(1).直接判断 _year == d._year && _month == d._month && _day == d._day 是否成立即可。

2.5日期类重载小于等于号(<=)

bool Data::operator<=(const Data& d) const
{
	return *this < d || *this == d;
}

(1).由于我们之前以及重载<以及==号,所以我们直接利用即可,当<成立或者==成立时,返回true。

2.6日期类重载大于号(>)

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

(1).我们之前重载了<=号,所以我们直接!(*this <= d)即可。

2.7重载大于等于号(>=)

bool Data::operator>=(const Data& d) const {
	return *this > d || *this == d;
}

(1).我们之前重载了>号和==号,如果>号成立或者==号成立,则返回true。

2.8重载不等于号(!=)

bool Data::operator!=(const Data& d) const
{
	return !(*this == d);
}

(1).已经实现了重载等于号(==),直接判断 !(*this == d) 即可。

2.9重载加等于号(+=)

Data& Data::operator+=(int day) {
	if (day < 0) {
		return *this -= (-day);
	}
	_day += day;
	while (_day > Data::getday(_year, _month))
	{
		_day -= getday(_year, _month);
		_month++;
		if (_month > 12) {
			_month = 1;
			_year++;
		}
	}
	return *this;
}

(1).首先要判断day是否为负,日期+(负数)相当于日期-天数,如果day小于0,则我们利用减等于号(-=)。

(2).首先让当前天数加上day,然后循环判断_day是否大于当前月的总天数,如果大于就先减去当前月的总天数,然后将月加一,要特判月大于12时,月要归1,年要加一。

(3).最后返回当前*this指针,因为是+=,是对自身加。

2.10重载减等于号(-=)

Data& Data::operator-=(int day) {
	if (day < 0) {
		return *this += (-day);
	}
	_day -= day;
	while (_day <= 0) {
		_month--;
		if (_month == 0) {
			_month = 12;
			_year--;
		}
		_day += getday(_year, _month);
	}
	return *this;
}

(1).首先要判断day是否为负,日期-(负数)相当于日期+天数,如果day小于0,则我们利用加等于号(+=)。

(2).首先让当前天数减去day,然后循环判断_day是否小于等于0,如果小于等于0就先将月减一,然后加上当前月的总天数,要特判月等于0时,月要置为12,年要减一。

(3).最后返回当前*this指针,因为是-=,是对自身减。

2.11重载加号(+)(日期+天数)

Data Data::operator+(int day) const {
	Data temp = *this;
	temp += day;
	return temp;
}

(1).因为是+号,并不是+=,没有对自身加,所以我们创建一个Data类,复制*this,然后我们使用重载+=,对temp自身加,然后返回temp即可。

2.12重载减号(-)(日期-天数)

Data Data:: operator-(int day) const
{
	Data temp = *this;
	temp -= day;
	return temp;
}

(1).因为是-号,并不是-=,没有对自身减,所以我们创建一个Data类,复制*this,然后我们使用重载-=,对temp自身减,然后返回temp即可。

2.13重载后置加加(后置++)

Data Data::operator++(int)
{
	Data temp = *this;
	temp += 1;
	return temp;
}

(1).后置++和前置++的区别为,在传参时,后置++要加上一个int。

(2).因为是后置++,所以是后赋值,我们创建一个Data类,对这个类+=1即可,最后返回temp。

2.14重载前置加加(++前置)

Data& Data::operator++()
{
	*this += 1;
	return *this;
}

 (1).因为是前置加加,所以是先自加然后再赋值,就要先改变自身,所以直接对*this+=1即可。

2.15重载后置减减(后置--)

Data Data:: operator--(int)
{
	Data temp = *this;
	temp -= 1;
	return temp;
}

(1).后置--和前置--的区别为,在传参时,后置--要加上一个int。

(2).因为是后置--,所以是后赋值,我们创建一个Data类,对这个类-=1即可,最后返回temp。

2.16重载前置减减(--前置)

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

 (1).因为是前置减减,所以是先自减然后再赋值,就要先改变自身,所以直接对*this-=1即可。

2.17重载减号(-)(日期-日期)

int Data::operator-(const Data& d) const {
	int ans = 0;
	Data temp1 = *this;
	Data temp2 = d;
	if (temp2 > temp1) {
		swap(temp2, temp1);
	}
	while (temp1 != temp2) {
		temp2 += 1;
		ans++;
	}
	return ans;
}

(1).我们创建两个Data类,一个存储 *this ,另一个存储d,并且判断那个那个小,把小的交换到temp2,然后循环判断temp1是否不等于temp2,若不等于就ans++,并且将temp2+=1,直到temp1和temp2相等。最后返回ans,即是两日期相差天数。

2.18重载<<号

ostream& operator<<(ostream& out, const Data& d)
{
	out << d._year << '/' << d._month << '/' << d._day << endl;
	return out;
}

(1).输出年月日,最后要返回out,因为如果要考虑到连续输出的情况,cout<<d1<<d2<<d3。

2.19重载>>号

istream& operator>>(istream& in, Data& d) {

	while (1)
	{
		in >> d._year >> d._month >> d._day;
		if (!d.CheckDate())
		{
			cout << "输入日期非法:";
			d.Print();
			cout << "请重新输入!!!" << endl;
		}
		else
		{
			break;
		}
	}
	return in;
}

(1).输入年月日,然后判断是否合法,如果合法就退出循环,否则一直重新输入。

(2).最后也是要返回in,因为要考虑到连续输入的情况,cin>>d1>>d2>>d3。

2.10 data.cpp源码

#include"data.h"


bool Data::operator<(const Data& d) const
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month < d._year)
		{
			return true;
		}
		else if (_month == d._month)
		{
			return _day < d._day;
		}
	}
	return false;
}


bool Data::operator==(const Data& d) const
{
	return _year == d._year && _month == d._month && _day == d._day;
}


bool Data::operator<=(const Data& d) const
{
	return *this < d || *this == d;


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

bool Data::operator>=(const Data& d) const {
	return *this > d || *this == d;
}


bool Data::operator!=(const Data& d) const
{
	return !(*this == d);
}


Data Data::operator+(int day) const {
	Data temp = *this;
	temp += day;
	return temp;
}
Data& Data::operator+=(int day) {

	if (day < 0) {
		return *this -= (-day);
	}
	_day += day;
	while (_day > Data::getday(_year, _month))
	{
		_day -= getday(_year, _month);
		_month++;
		if (_month > 12) {
			_month = 1;
			_year++;
		}
	}
	return *this;
}

Data Data:: operator-(int day) const
{
	Data temp = *this;
	temp -= day;
	return temp;
}

Data& Data::operator-=(int day) {

	if (day < 0) {
		return *this += (-day);
	}

	_day -= day;

	while (_day <= 0) {
		_month--;
		if (_month == 0) {
			_month = 12;
			_year--;
		}
		_day += getday(_year, _month);
	}
	return *this;
}


Data Data::operator++(int)
{
	Data temp = *this;
	temp += 1;
	return temp;
}

Data& Data::operator++()
{
	*this += 1;
	return *this;
}

Data Data:: operator--(int)
{
	Data temp = *this;
	temp -= 1;
	return temp;
}

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

int Data::operator-(const Data& d) const {
	int ans = 0;
	Data temp1 = *this;
	Data temp2 = d;
	if (temp2 > temp1) {
		swap(temp2, temp1);
	}
	while (temp1 != temp2) {
		temp2 += 1;
		ans++;
	}
	return ans;
}

ostream& operator<<(ostream& out, const Data& d)
{
	out << d._year << '/' << d._month << '/' << d._day << endl;
	return out;
}


istream& operator>>(istream& in, Data& d) {

	while (1)
	{
		in >> d._year >> d._month >> d._day;
		if (!d.CheckDate())
		{
			cout << "输入日期非法:";
			d.Print();
			cout << "请重新输入!!!" << endl;
		}
		else
		{
			break;
		}
	}
	return in;
}

bool Data::CheckDate()const
{
	if (_month <= 0 || _month > 12 || _day<1 || _day>getday(_year, _month)) {
		return false;
	}
	return true;
}

void Data::Print()const {
	cout << _year << '/' << _month << '/' << _day << endl;
}

Data::Data(int year, int month, int day) {

	_year = year;
	_month = month;
	_day = day;
	if (!CheckDate())
	{
		cout << "非法日期:";
		Print();
	}
}


本篇完

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mike!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值