[detailed implementation and analysis of date class]

Operations on date class objects:

In life, we are certainly familiar with dates. For example, all kinds of festivals have to use a date to define which day it is; As for the date, we might as well classify it as a class. In real life, the date is an entity. We build the date as a date class. Let's implement the related operations often used on the date class.

1. Construction of date class

We know that a date is described by the year, month and day. Therefore, when we build a date class with a user-defined type, the members of the date class are year, month and day. The member functions of the date class are used to implement various operations on the date class. The construction is as follows:

#include <iostream>
using namespace std;

//Date class
class Date
{
public:
	void Print();
	int GetMonthDay(int year, int month);
	Date(int year=0,int month=0,int day=0); //Constructor
	Date(const Date& d);   //copy constructor 

	//Operator overload to judge the size relationship between two date classes
	bool operator>(Date& d);
	bool operator==(Date& d);
	bool operator>=(Date& d) ;
	bool operator<(Date& d);
	bool operator<=(Date& d);
	bool operator!=(Date& d);
    
    //Implement the result of adding or subtracting one day from the date class
	Date& operator+=(int n);
	Date operator+(int n) const;
	Date& operator-=(int n);
	Date operator-(int n);

    //Number of days to achieve the difference between two dates
	int operator-(const Date& d);
    
    //Self increment and self decrement of realization date
	Date& operator++();
	Date operator++(int);
	Date& operator--();
	Date operator--(int);

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

2. Function to get the number of days of each month

For dates, it is of great significance to obtain the number of days of each month, because the results caused by different years and months have particularity. For example, in February of each year, it is necessary to judge whether it is a wet year or a normal year. If it is a normal year, it is 28 days, and a wet year is 29 days. In addition, this function is also required to realize the operation of other dates. The function to obtain the days of each month is as follows:

//The function to get the number of days of each month in the date class
int Date::GetMonthDay(int year, int month)
{
	static int sum[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int day = sum[month];

	//Judge whether it is a wet year and February
	if ((month == 2) &&
	((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
	{
		day++;
	}
	return day;
}

3. Constructor

We know that when we create a date class, the compiler will call the constructor for us. If we do not implement the constructor, the compiler will automatically generate one for us. However, the automatically generated default constructor does not process the built-in type, so the object cannot be initialized; Therefore, we must write a constructor ourselves, and this constructor also needs to judge whether the date is reasonable. For example, the date 2022.15.52 is unreasonable. The constructor is as follows:

//Print date function
void Date::Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

Date::Date(int year, int month, int day)
{
	//Initialize first
	_year = year;
	_month = month;
	_day = day;
	//Then judge whether the date is reasonable
	if((year<1) || (month>12&&month<1) 
		|| (day > GetMonthDay(year, month)))
	{
		cout << "Illegal date:" ;
		Print();
	}
}

4. Judge the size relationship between two dates

In the previous C language syntax, we can only perform operator operations on built-in types, not on user-defined types (such as structures); In order to enhance the readability of the code, C + + introduces operator overloading, which is a function with a special function name; Therefore, we can operate operators on user-defined types to realize the size relationship between two dates. The implementation functions are as follows:

//Judge whether the date d1 prints the date d2
bool Date::operator>(Date& d)
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month > d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month && _day > d._day)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//Judge whether the two dates are the same
bool Date::operator==(Date& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)
	{
		return true;
	}
	return false;
	
}

//Reuse the operators > and = = previously implemented
bool Date::operator>=(Date& d) 
{
	return (*this > d) || (*this == d);
}

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

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

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

5. Realization of date plus or minus days

We still have a lot to implement for date class objects. For example, in daily life, we want to know how much a date plus or minus a certain day is, and we need to be able to implement it in date class. In the following implementation of + =, + and -, - = operators, we should note that + = can change itself, while + cannot change itself; The functions are as follows:

//What is the date plus the number of days
Date& Date::operator+=(int n)
{
	//If the number of days is negative, the - = operator is multiplexed
	if (n < 0)
	{
		return *this -= n;
	}

	_day += n;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

Date Date::operator+(int n) const
{
	Date ret = *this;
	ret += n;
	return ret;
}

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

Date Date::operator-(int n)
{
	Date ret = *this;
	ret -= n;
	return ret;
}

6. Realization of date minus date

In daily life, adding a date to a date is meaningless, but subtracting a date from a date is the number of days between two dates, which is of great significance. We can also implement it in the class. The function is as follows:

//Date - date. The parameter is of type date. It forms an overload with the above date minus days function
int Date::operator-(const Date& d)
{
	int count = 0;
	int flag = 1;
	Date Max = *this;
	Date Min(d);
	if (Min>Max)
	{
		Max = d;
		Min = *this;
		flag = -1;
	}
	while (Min != Max)
	{
		Min += 1;
		count++;
	}
	return count * flag;
}

7. Self increase and self decrease of date

Self increment and self decrement are often used in operators. We can also implement self increment and self decrement of user-defined date classes, but they should be divided into pre + + or post + +; Pre + + changed the self increment before use, and changed itself; The latter + + is used first and then self incremented; We should pay attention to the differences.

//Pre + +, reuse the + = operator
Date& Date::operator++()
{
	*this += 1;
	return *this;
}

//Post + +, which has not changed before use
Date Date::operator++(int)
{
	Date ret = *this;
	*this += 1;
	return ret;
}

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

//Post--
Date Date::operator--(int)
{
	Date ret = *this;
	*this -= 1;
	return ret;
}

Keywords: C++

Added by jasonscherer on Mon, 24 Jan 2022 02:42:01 +0200