//--------------------------------------------------------------------------
	      /*
	      **名称:日期的简单操作
	      **
	      **
          **类函数:构造函数,拷贝构造函数,析构函数,操作符重载函数
	      **
	      **日期类操作函数: 1:计算一个日期加上多少天数后的日期       
	      **                2:把该日期改为加上指定数目的天数后的日期
	      **                3:一个日期减上多少天数后的日期 
	      **                4:该日期加1(前置++)(后置++)
	      **                5:该日期减1(前置--)(后置--)
	      **                6:计算某日期到未来某日期间隔的天数
	      **
	      **
	      **日期:2016/1/13
	      */
//---------------------------------------------------------------------------
/*----------------------------------------头文件--------------------------------------*/

# ifndef __DATA_H__
# define __DATA_H__

# define _CRT_SECURE_NO_WARNINGS 1

# include <iostream>
# include <stdlib.h>
# include <assert.h>


using namespace std;

class Date
{
public:
	//打印函数
	void Display();
public:
	//构造函数
	Date(size_t year, size_t month, size_t day);
	//拷贝构造函数
	Date(const Date & d);
	//析构函数
	~Date();
	//操作符重载
	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=(const Date & d);
	
	//日期类操作
	Date operator+ (size_t day);
	Date& operator+= (size_t day);

	Date operator- (size_t day);
	Date& operator-= (size_t day);

	Date& operator++();
	Date operator++(int);

	Date& operator--();
	Date operator--(int);

	int Date::operator-(const Date & d);

private:
	bool _IsLeapYear(size_t year);
	size_t _GetMonthDay(size_t year, size_t month);


private:
	size_t _year;
	size_t _month;
	size_t _day;
};


# endif   //__DATA_H__
/*------------------------------------功能函数-----------------------------------------*/

# include "Date.h"

//打印函数
void Date::Display()
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

//构造函数
Date::Date(size_t year = 1900, size_t month = 1, size_t day = 1)
{
	if (year > 0 && month > 0 && month<13 && day>0 
	    && day <= _GetMonthDay(year, month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "初始化数据非法" << endl;
		_year = 1900;
		_month = 1;
		_day = 1;
	}
}

//拷贝和构造函数
Date::Date(const Date & d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

//析构函数
Date::~Date()
{
	//do_nothing
}

/*操作符重载*/
bool Date::operator==(const Date & d)
{
	return (_year == d._year)
		&& (_month == d._month)
		&& (_day == d._day);
}

bool Date::operator>(const 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;
	}
	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);
}

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

	return *this;
}

/*日期类操作*/
//判断是否为闰年
bool Date::_IsLeapYear(size_t year)
{
	return ((0 == year % 4 && 0 != year % 100) || (0 == year % 400));
}

//返回指定月的天数
size_t Date::_GetMonthDay(size_t year, size_t month)
{
	size_t MonthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	size_t MonthDays = MonthArray[month];
	bool ret;

	if ((2 == month) && (ret = _IsLeapYear(year)))
	{
		MonthDays = 29;
	}

	return MonthDays;
}

//一个日期加上多少天数后的日期
Date Date::operator+ (size_t day)
{
	size_t MonthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	Date tmp(*this);
	size_t SumDays = tmp._day + day;

	while (true)
	{
		if (SumDays <= _GetMonthDay(tmp._year, tmp._month))
		{
			tmp._day = SumDays;
			return tmp;
		}
		else
		{
			SumDays -= _GetMonthDay(tmp._year, tmp._month);
			tmp._month++;
			if (tmp._month > 12)
			{
				tmp._year++;
				tmp._month %= 12;
			}
		}
	}
}

//把该日期改为加上指定数目的天数后的日期
Date& Date::operator+= (size_t day)
{
	*this = operator+(day);
	return *this;
}

//一个日期减上多少天数后的日期 
Date Date::operator- (size_t day)
{
	size_t MonthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	Date tmp(*this);
	size_t SumDays = tmp._day + day;

	while (true)
	{
		if (day < tmp._day)
		{
			tmp._day -= day;
			return tmp;
		}
		else
		{
			day -= tmp._day;
			if (1 == tmp._month)
			{
				tmp._year--;
				tmp._month = 12;
			}
			else
			{
				tmp._month--;
			}
			tmp._day = _GetMonthDay(tmp._year, tmp._month);
		}
	}
}

//把该日期改为减上指定数目的天数后的日期
Date& Date::operator-= (size_t day)
{
	*this = operator-(day);
	return *this;
}

//该日期加1(前置++)
Date& Date::operator++()
{
	++_day;
	if (_day > _GetMonthDay(_year, _month))
	{
		_day %= _GetMonthDay(_year, _month);

		++_month;
		if (_month > 12)
		{
			++_year;
			_month %= 12;
		}
	}

	return *this;
}

//日期加1(后置++)
Date Date::operator++(int)
{
	Date tmp(*this);
	
	*this = operator++();

	return tmp;
}

//该日期减1(前置--)
Date& Date::operator--()
{
	if (_day > 1)
	{
		--_day;
	}
	else
	{
		if (1 == _month)
		{
			--_year;
			_month = 12;
			_day = _GetMonthDay(_year,_month);
		}
		else
		{
			--_month;
			_day = _GetMonthDay(_year, _month);
		}
	}

	return *this;
}

//该日期减1(后置--)
Date Date::operator--(int)
{
	Date tmp(*this);
	*this = operator--();

	return tmp;
}

//返回指定日期减去该日期后的天数
int Date::operator-(const Date & d)
{
	//异常:该日期比被减日期小
	if (d._year < _year)
	{
		return -1;
	}
	else if (d._year == _year && d._month < _month)
	{
		return -1;
	}
	else if (d._year == _year && d._month == _month && d._day < _day)
	{
		return -1;
	}

	//正常情况
	Date tmp_d(d);
	Date tmp_d_day(*this);
	int ret = 0;

	while (!(tmp_d == tmp_d_day))
	{
		tmp_d_day.operator++();
		ret++;
	}
	return ret;
}	
/*------------------------------------部分测试用例-------------------------------------*/

# include "Date.h"


//测试operator<=()
void Test7()
{
	//false
	Date d1(2016, 1, 12);
	Date d2(2016, 1, 11);
	bool ret = d1 <= d2;
	d1.Display();
	d2.Display();
	cout << ret << endl;

	//false
	Date d3(2016, 1, 12);
	Date d4(2015, 1, 12);
	ret = d3 <= d4;
	d3.Display();
	d4.Display();
	cout << ret << endl;

	//true
	Date d5(2016, 1, 12);
	Date d6(2016, 1, 13);
	ret = d5 <= d6;
	d5.Display();
	d6.Display();
	cout << ret << endl;

	//false
	Date d7(2016, 1, 12);
	Date d8(2016, 1, 12);
	ret = d7 <= d8;
	d7.Display();
	d8.Display();
	cout << ret << endl;

}
//测试operator>=()
void Test6()
{
	//true
	Date d1(2016, 1, 12);
	Date d2(2016, 1, 11);
	bool ret = d1 >= d2;
	d1.Display();
	d2.Display();
	cout << ret << endl;

	//true
	Date d3(2016, 1, 12);
	Date d4(2015, 1, 12);
	ret = d3 >= d4;
	d3.Display();
	d4.Display();
	cout << ret << endl;

	//false
	Date d5(2016, 1, 12);
	Date d6(2016, 1, 13);
	ret = d5 >= d6;
	d5.Display();
	d6.Display();
	cout << ret << endl;
	
	//true
	Date d7(2016, 1, 12);
	Date d8(2016, 1, 12);
	ret = d7 >= d8;
	d7.Display();
	d8.Display();
	cout << ret << endl;
}
//测试operator<()
void Test5()
{
	//false
	Date d1(2016, 1, 12);
	Date d2(2016, 1, 11);
	bool ret = d1 < d2;
	d1.Display();
	d2.Display();
	cout << ret << endl;

	//false
	Date d3(2016, 1, 12);
	Date d4(2015, 1, 12);
	ret = d3 < d4;
	d3.Display();
	d4.Display();
	cout << ret << endl;

	//true
	Date d5(2016, 1, 12);
	Date d6(2016, 1, 13);
	ret = d5 < d6;
	d5.Display();
	d6.Display();
	cout << ret << endl;
}

//测试operator>()
void Test4()
{
	//true
	Date d1(2016, 1, 12);
	Date d2(2016, 1, 11);
	bool ret = d1 > d2;
	d1.Display();
	d2.Display();
	cout << ret << endl;

	//false
	Date d3(2016, 1, 12);
	Date d4(2016, 1, 12);
	ret = d3 > d4;
	d3.Display();
	d4.Display();
	cout << ret << endl;

	//false
	Date d5(2016, 1, 12);
	Date d6(2016, 1, 13);
	ret = d5 > d6;
	d5.Display();
	d6.Display();
	cout << ret << endl;

}

//测试operator==
void Test3()
{
	//false
	Date d1(2016, 1, 12);
	Date d2(2016, 1, 11);
	bool ret = d1 == d2;
	d1.Display();
	d2.Display();
	cout << ret << endl;

	//true
	Date d3(2016, 2, 12);
	Date d4(2016, 1, 12);
	ret = d3 == d4;
	d3.Display();
	d4.Display();
	cout << ret << endl;

	//false
	Date d5(2016, 1, 12);
	Date d6(2016, 1, 13);
	ret = d5 == d6;
	d5.Display();
	d6.Display();
	cout << ret << endl;

}

//测试Date(const Date & d)
void Test2()
{
	Date d1(2016, 1, 12);
	d1.Display();
	
	Date d2(d1);
	d2.Display();

	Date d3 = d1;
	d3.Display();
}

//测试Date(size_t year = 0, size_t month = 0, size_t day = 0)
void Test1()
{
	Date d(2016, 1, 12);
	d.Display();
}

//测试operator+ (size_t day)
void Test()
{
	Date d1(2016, 1, 13);
	d1.Display();

	cout << "+366天" << endl;
	Date ret = d1.operator+ (366);
	ret.Display();
}

//测试operator+= (size_t day)
void Test8()
{
	Date d1(2016, 1, 13);
	d1.Display();

	cout << "+10天" << endl;
	Date ret = d1.operator+= (18);
	ret.Display();
}

//测试operator- (size_t day)
void Test9()
{
	Date d1(2016, 1, 10);
	d1.Display();

	cout << "+375天" << endl;
	Date ret = d1.operator- (375);
	ret.Display();
}

//测试operator++()/operator++(int)
void Test10()
{
	Date d1(2016, 2, 29);
	d1.operator++();

	d1.Display();

	Date d2(2016, 3, 3);
	d2.operator--();

	d2.Display();
}

//测试operator--(int)/operator--()
void Test11()
{
	Date d1(2016, 12, 31);
	Date ret = d1.operator++(int());
	
	ret.Display();

	Date d2(2016, 12, 31);
    ret = d2.operator--(int());

	ret.Display();
}

//测试operator-(const Date & d)
void Test12()
{
	Date d1(2016, 1, 13);
	Date d2(1970, 1, 1);
	int ret = d2.operator-(d1);
	
	cout << "起始日期" << endl;
	d2.Display();
	cout << "截止日期" << endl;
	d1.Display();
	cout<<"间隔"<< ret << "天" << endl;
}

int main()
{
	//Test();
	//Test1();
	//Test2();
	//Test3();
	//Test4();
	//Test5();
	//Test6();
	//Test7();
	//Test8();
	//Test9();
	//Test10();
	//Test11();
	Test12();

	system("pause");
	return 0;
}