時間類的實現

要求Date.h

Date.h

#pragma once
#include<iostream>
using namespace std;

 class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1);

	// Date(const Date& d);
	// Date& operator=(const Date& d);
	// ~Date();
//兩個時間的比較
	inline bool operator>(const Date& d);
	inline bool operator<(const Date& d);
	inline bool operator<=(const Date& d);
	inline bool operator>=(const Date& d);
	inline bool operator==(const Date& d);
	inline bool operator!=(const Date& d);

//時間的加減法運算
	Date operator+(int day);
	Date& operator+=(int day);
	Date operator-(int day);
	Date& operator-=(int day);
	int operator-(const Date& d);
	Date operator++(); // ++d => d.operator++(&d)
	Date operator++(int); // d++ => d.operator(&d, 0);
	Date operator--(); // --d 
	Date operator--(int); // d--
	
	//重複調用次數比較多,定義爲內斂
	inline int GetMonthDay(int year, int month);
	
	//距離1年1月1日的天數
	int Date::GetDays(const Date& d);

	void Print();
private:
	int _year;
	int _month;
	int _day;
};

其中幾個巧妙實現的函數

(1)比較日期

優化程序
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 true;
			}
		}
	}
	else
	{

	}
	return false;
}

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

(2)計算日期的加法

優化程序
1.因爲有平年和閏年之分所以
定義GetMonthDay(int year, int month)得到某年某月的總天數。
先直接把天數加到_day上,如果_day大於當前月的天數,就月份遞增,天數減少,然後繼續這個過程。
2.我們可以先實現+=然後再實現+
因爲如果先實現+再實現+=會多一次拷貝數據的次數。
3.變量的前置和後置++,我們選擇前置,因爲後置++比前置++多了兩次數據的拷貝。
4.注意day爲負數的情況,如果day爲負數,就直接調用減法進行運算

int Date::GetMonthDay(int year, int month)
{
										//1	 2	 3	 4	 5	 6	 7	 8	 9	 10	 11	 12
	const 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& Date::operator+=(int day)
{
	if (day<0)
	{
		return Date::operator-=(-day);
	}
	Date &tmp=(*this);
	tmp._day += day;
	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	{
		tmp._day -= GetMonthDay(tmp._year, tmp._month);
		++tmp._month;
		if (tmp._month > 12)
		{
			tmp._month = 0;
			++tmp._year;
		}
	}
	return tmp;
}

(3)計算日期的減法

程序優化
1.實現方法和加法類似。
2.這裏實現的是-,建議先實現-=再實現=。
3.前置–比後置–更加好,少兩次拷貝

//注意day爲負的情況
Date Date::operator-(int day)//這裏返回值只能用Date 而不能是Date&
{
	if (day < 0)
	{
		return Date::operator+(-day);
	}
	Date tmp(*this);
	tmp._day -= day;
	while (tmp._day <= 0)
	{
		//月份減1
		--tmp._month;
		//年份減1
		if (tmp._month == 0)
		{
			tmp._month = 12;
			--tmp._year;
		}
		//加上上個月的天數
		tmp._day += GetMonthDay(tmp._year,tmp._month);
	}
	return tmp;//一次
}

(4)計算日期之差

程序優化
方法1-巧
1.分別計算兩個時間距離公元第一天的天數
2.兩個天數之差就是日期之差
3.日期之差是正數
方法2-暴力
讓比較小的日期不斷增加直到與大的日期相等,記錄增加的天數,增加的天數就是日期之差。

方法1代碼

int Date::GetDays(const Date& d)
{
	int ret = 0;
	ret += d._day-1;//因爲沒有0年
	for (int i = 1; i < d._month; i++)
	{
		ret += GetMonthDay(d._year, i);
	}
	ret += d._year * 365 + d._year / 400 + d._year / 4 - d._year / 4;
	return ret;
}

//得到兩個日期的天數之差
int Date::operator-(const Date& d)
{

	//計算兩個日期離0年0月0日差  再求兩者之差
	int ret = 0;
	int d1 = GetDays(*this);
	int d2 = GetDays(d);
	if (d1 >= d2)
	{
		return d1 - d2;
	}
	else
	{
		cout << "Date Invalid" << endl;
	}
	return 0;
}

完整代碼Date.c

Date.c

#include"Date.h"


Date::Date(int year, int month, int day)
{
	if (year > 0 &&
		month > 0 && month<13 &&
		day>0 && day <= GetMonthDay(year,month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "Date Invalid" << endl;
	}

}

// Date(const Date& d);
// Date& operator=(const Date& d);
// ~Date();

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 true;
			}
		}
	}
	else
	{

	}
	return false;
}

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 || ((*this) == d));
}

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);
}


//注意day爲負的情況
Date Date::operator+(int day)
{
	Date tmp(*this);//一 //這樣只有兩次拷貝
	(*this) += day;
	return tmp;//二
}

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



//注意day爲負的情況
Date Date::operator-(int day)//這裏返回值只能用Date 而不能是Date&
{
	if (day < 0)
	{
		return Date::operator+(-day);
	}
	Date tmp(*this);
	tmp._day -= day;
	while (tmp._day <= 0)
	{
		//月份減1
		tmp._month--;
		//年份減1
		if (tmp._month == 0)
		{
			tmp._month = 12;
			tmp._year--;
		}
		//加上上個月的天數
		tmp._day += GetMonthDay(tmp._year,tmp._month);
	}
	return tmp;//一次
}

Date& Date::operator-=(int day)
{
	Date &tmp = (*this);
	tmp = tmp - day;//這裏有兩次拷貝,tmp拷貝到臨時變量,臨時變量再拷貝到接收的變量
	return tmp;
}

//得到兩個日期的天數之差
int Date::operator-(const Date& d)
{

	//計算兩個日期離0年0月0日差  再求兩者之差
	int ret = 0;
	int d1 = GetDays(*this);
	int d2 = GetDays(d);
	if (d1 >= d2)
	{
		return d1 - d2;
	}
	else
	{
		cout << "Date Invalid" << endl;
	}
	return 0;
}

// ++d => d.operator++(&d)
Date Date::operator++()
{
	

	(*this) = (*this) + 1;
	return (*this);
}

// d++ => d.operator(&d, 0);
Date Date::operator++(int)
{
	Date tmp(*this);
	(*this) = (*this) + 1;
	return tmp;
}

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

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

int Date::GetMonthDay(int year, int month)
{
										//1	 2	 3	 4	 5	 6	 7	 8	 9	 10	 11	 12
	const 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];
}

//這個函數計算的是距離公元后第一天的天數
int Date::GetDays(const Date& d)
{
	int ret = 0;
	ret += d._day-1;//因爲沒有0年
	for (int i = 1; i < d._month; i++)
	{
		ret += GetMonthDay(d._year, i);
	}
	ret += d._year * 365 + d._year / 400 + d._year / 4 - d._year / 4;
	return ret;
}


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章