1. 程式人生 > >C++ 宣告並實現一個日期類(運算子過載)

C++ 宣告並實現一個日期類(運算子過載)

/******************************************************************************************
date.hpp:
	Copyright (c) Bit Software, Inc.(2013), All rights reserved.

Purpose:
	宣告並實現一個日期類

難度:***

Author:
	xxx

Created Time:
	2015-4-26
******************************************************************************************/

#ifndef DATE_HPP_INCLUDED
#define DATE_HPP_INCLUDED
#include <iostream>
using namespace std;

class Date
{
public:
	Date (int year = 1, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		// 檢查如果輸入引數是非法時間,則初始化為1990-1-1
		if (check_is_valid_date () == false)
		{
			year = 1990;
			month = 1;
			day = 1;
		}
	}

	Date (const Date& d)
		:_year(d._year)
		,_month(d._month)
		,_day(d._day)
	{}

	// 思考為什麼operator=賦值函式需要一個date&的返回值??
	Date& operator= (const Date& d)
	{
		if (this != &d)
		{
			this->_year = d._year;
			this->_month = d._month;
			this->_day = d._day;
		}

		return *this;
	}

	~Date()
	{}

	// 檢查時間是否有效
	bool check_is_valid_date ()
	{
		if (_year < 1
			|| (_month < 1 || _month > 12)
			|| (_day < 1   || _day > day_of_month (_year, _month)))
		{
			return false;
		}

		return true;
	}

	void display ()
	{
		cout<<_year<<"-"<<_month<<"-"<<_day<<endl<<endl;
	}

public:
	// static修飾成員函式是靜態成員函式,不明白的查一下資料!
	// 返回一個月的天數,日期非法則返回0
	// 這個函式這是一種優化的思路,你還有其他的邏輯思路嗎?請實現!
	static int day_of_month (int year, int month)
	{
		if (year < 1 || month < 1 || month > 12) {
			return 0;
		}

		int month_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

		// 瑞年的2月是29天
		month_days[2] += is_leap_year(year);

		return month_days[month];
	}

	// 判斷是否為瑞年。
	// 另外請思考為什麼瑞年是這樣計算,而不直接是year % 4 == 0就是瑞年???
	static bool is_leap_year (int year)
	{
		if ((year % 4 == 0 && year % 100 != 0)
			|| year % 400 == 0)
		{
			return true;
		}

		return false;
	}

	// 請實現下面的運算子過載
public:
	// 計算日期 +/- 一定天數以後的日期
	Date operator+(int day)
	{
	    if( (_day+day) > day_of_month(_year,_month) )
        {
            _month = _month+1;
            _day = day - (day_of_month(_year,_month) - _day) + 1;
            if(_day == 0)
            {
                _day += 1;
            }
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        else
        {
            _day=_day+day;
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        return Date(_year,_month,_day);
	}

	Date& operator+=(int day)
	{
	    if( (_day+day) > day_of_month(_year,_month) )
        {
            _month = _month+1;
            _day = day - (day_of_month(_year,_month) - _day) + 1;
            if(_day == 0)
            {
                _day += 1;
            }
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        else
        {
            _day=_day+day;
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        return *this;
	}

	Date operator-(int day)
	{
	    if( (_day-day) <= 0 )
        {
            _month = _month-1;
            if(_month == 0)
            {
                _month = 12;
            }
            if(_day == 0)
            {
                _day = day_of_month(_year,_month);
            }
            _day=_day-day;
            _day = day_of_month(_year,_month) + _day;

            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        else
        {
            _day=_day-day;
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        return Date(_year,_month,_day);
	}
	Date& operator-=(int day)
	{
	    if( (_day-day) <= 0 )
        {
            _month = _month-1;
            if(_month == 0)
            {
                _month = 12;
            }
            if(_day == 0)
            {
                _day = day_of_month(_year,_month);
            }
            _day=_day-day;
            _day = day_of_month(_year,_month) + _day;

            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        else
        {
            _day=_day-day;
            cout<<"month = "<<_month<<"day = "<<_day<<endl;
        }
        return *this;
	}

    // 另外日期 + 日期沒有意義?       //沒有意義

	// 計算日期 - 日期以後的天數。
	int operator-(const Date& d)
	{
        int i = 0;
        int j = 0;
        int value;
        for(;_year<0;_year--)
        {
            if(is_leap_year(_year) == true)
            {
                i +=_year * 366;
            }
            else
            {
                i +=_year * 365;
            }
        }
        int tmp = d._year;
        for(;tmp<0;tmp--)
        {
            if(is_leap_year(tmp) == true)
            {
                j += tmp * 366;
            }
            else
            {
                j += tmp * 365;
            }
        }
            int p = _month;
		while(p)
		{
			i += day_of_month(_year,_month);
			p--;
		}
		int q = d._month;
		while(q)
		{
			j += day_of_month(tmp,d._month);
			q--;
		}
            i += _day;
            j += d._day;
            value = i - j;
		if(value < 0)
        {
            value=-value;
        }
            cout<<"相差天數"<<value<<endl;
            return value;
	}

	Date operator++()
	{
        ++_day;
		if(_day > day_of_month(_year,_month))
		{
			_day = 1;
			_month++;
			if(_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
	}
	Date& operator++(int) // 後置++
	{
	    _day++;
		if(_day > day_of_month(_year,_month))
		{
			_day = 1;
			_month++;
			if(_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	Date operator--()
	{
	    --_day;
		if(_day < 1)
		{
		    _month--;
		    _day=day_of_month(_year,_month);
			if(_month < 1)
			{
				_year--;
				_month = 12;
			}
		}
	}
	Date& operator--(int) // 後置--
	{
	    _day--;
		if(_day < 1)
		{
		    _month--;
		    _day=day_of_month(_year,_month);
			if(_month < 1)
			{
				_year--;
				_month = 12;
			}
		}
		return *this;
	}

	bool operator > (const Date& d)
	{
	    if(_year > d._year)
		{
			cout<<"True\n";
			return true;
		}
		else
		{
            if(_month > d._month)
            {
                cout<<"True\n"<<endl;
                return true;
            }
            else
            {
                if(_day > d._day)
                {
                    cout<<"True"<<endl;
                    return true;
                }
                else
                {
                    cout<<"Falese\n"<<endl;
                    return false;
                }
            }
        }
		cout<<"false\n";
		return false;
	}
	bool operator >= (const Date& d)
	{
	    if(_year > d._year)
		{
			cout<<"True\n";
			return true;
		}
		else if(_year < d._year)
        {
            cout<<"False"<<endl;
            return false;
        }
		else
		{
            if(_month > d._month)
            {
                cout<<"True\n"<<endl;
                return true;
            }
            else if(_month < d._month)
            {
                cout<<"False\n"<<endl;
                return false;
            }
            else
            {
                if(_day > d._day)
                {
                    cout<<"True"<<endl;
                    return true;
                }
                else if(_day < d._day)
                {
                    cout<<"False\n"<<endl;
                    return false;
                }
                else
                {
                    cout<<"Falese\n"<<endl;
                    return false;
                }
            }
        }
		cout<<"false\n";
		return false;
	}

	bool operator < (const Date& d)
	{
	    if(_year < d._year)
		{
			cout<<"True\n";
			return true;
		}
		else
		{
            if(_month < d._month)
            {
                cout<<"True\n"<<endl;
                return true;
            }
            else
            {
                if(_day < d._day)
                {
                    cout<<"True"<<endl;
                    return true;
                }
                else
                {
                    cout<<"Falese\n"<<endl;
                    return false;
                }
            }
        }
		cout<<"false\n";
		return false;
	}
	bool operator <= (const Date& d)
	{
	    if(_year < d._year)
		{
			cout<<"True\n";
			return true;
		}
		else if(_year > d._year)
        {
            cout<<"False"<<endl;
            return false;
        }
		else
		{
            if(_month < d._month)
            {
                cout<<"True\n"<<endl;
                return true;
            }
            else if(_month > d._month)
            {
                cout<<"False\n"<<endl;
                return false;
            }
            else
            {
                if(_day < d._day)
                {
                    cout<<"True"<<endl;
                    return true;
                }
                else if(_day > d._day)
                {
                    cout<<"False\n"<<endl;
                    return false;
                }
                else
                {
                    cout<<"False\n"<<endl;
                    return false;
                }
            }
        }
		cout<<"False\n";
		return false;
	}

	bool operator == (const Date& d)
	{
	    if(_day == d._day && _month ==d._month && _year == d._year)
        {
            return true;
        }
        else
        {
            return false;
        }
	}
	bool operator != (const Date& d)
	{
	    if(_day == d._day && _month ==d._month && _year == d._year)
        {
            cout<<"False"<<endl;
            return false;
        }
        else
        {
            cout<<"True"<<endl;
            return true;
        }
	}

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

void test_date1 ()
{
	// 正常日期測試
	Date d1(2015, 4, 26);
	d1.display ();

	// 非法日期測試
	Date d2(2015, 2, 30);
	d2.display ();

	Date d3(d1);
	d3.display();

	d3 = d2;
	d3.display ();

	int year = 2000;
	if (Date::is_leap_year (year))
	{
		cout<<year<<" is leap year"<<endl;
	}
	else
	{
		cout<<year<<" is not leap year"<<endl;
	}

	int month = 5;
	cout<<"day of "<<month<<" month:"<<Date::day_of_month(year, month)<<endl<<endl;

	year = 1999;
	if (Date::is_leap_year (year))
	{
		cout<<year<<" is leap year"<<endl;
	}
	else
	{
		cout<<year<<" is not leap year"<<endl;
	}

	cout<<"day of "<<month<<" month:"<<Date::day_of_month(year, month)<<endl<<endl;
}
#endif // DATE_HPP_INCLUDED