1. 程式人生 > >c++實現簡單日期類

c++實現簡單日期類

概要

下面這一大塊程式碼主要練習了 運算子過載。設定了一個日期類。如有問題請看註釋。

//Date.h
#include<iostream>
#include<Windows.h>
using namespace std;

class Day
{
private:
	int _year;
	int _month;
	int _day;
public:
	Day(int year = 2018, int month = 10, int day = 30);
	bool _IsLeapyear(int year);
	int _GetDaysOfMonth(int year, int month);
	void Create_Day(int year, int month, int day);
	friend ostream & operator << (ostream &_cout, const Day &d);
	friend Day operator ++(Day &d, int);
	friend Day & operator ++(Day &d);
	friend Day  operator +(Day d1, int days);
	friend Day  operator -(Day d1, int days);
	friend bool operator == (const Day &d1,const Day &d2);
	friend bool operator <(const Day &d1, const	Day &d2);
	friend bool operator >(const Day &d1,const Day &d2);
	friend bool operator <=(const Day &d1,const Day &d2);
	friend bool operator >=(const Day &d1,const Day &d2);
	Day  operator = (Day d1);
	int Get_year();
	int Get_month();
	int Get_day();
};


class cal
{
private:
	Day date;
	char* Week[12];
	int* year1[12];
	int* year2[12];
public:
	void Setinfo();
	void Setyear(int** year);
	void Inityear1(int **year);
	void Inityear2(int **year);
	void PrintCal();
	void PrintCal_();
	int FindDay();
	int Zeller(int a, int b, int c);
};

//Date.cpp
#include"Date.h"
/***************************

這個函式是用來獲得 _year的值

****************************/
int Day :: Get_year()
{
	return _year;
}
/***************************

這個函式是用來獲得 _month的值

****************************/
int Day::Get_month()
{
	return _month;
}
/***************************

這個函式是用來獲得 _day的值

****************************/
int Day::Get_day()
{
	return _day;
}
/***************************

這個函式是用來設定一個日期的值

****************************/
void Day::Create_Day(int year, int month, int day)
{
	_year = year;
	_month = year;
	_day = day;
}
/***************************

這個函式是建構函式,日期不正確
則會報錯,並且將日期設定為預設值
1900 - 1 - 1
預設定義為
2018 - 10 - 30

****************************/
Day:: Day(int year , int month, int day) :_year(year), _month(month), _day(day)
{
	if (!(year > 0 && month >=1 && month <= 12 && (day <= _GetDaysOfMonth(year, month))))
	{
		printf("Day :: Day failed -> init default data 1900 - 1 -1 !\n");
		_year = 1900;
		_month = 1;
		_day = 1;
	}
}
/***************************

這個函式是用來檢測year是不是閏年

****************************/
bool Day::_IsLeapyear(int year)
{
	if (((year % 4 == 0) && (year % 100 != 0)) || year % 400 == 0)
	{
		return true;
	}
	return false;
}
/***************************

這個函式是用來獲取某個月有多少天

****************************/
int Day :: _GetDaysOfMonth(int year, int month)
{
	int Mon[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	if (2 == month && _IsLeapyear(year))
	{
		return Mon[month] + 1;
	}
	return Mon[month];
}
/***************************

這個函式是用來初始化一個 year[12]
陣列的,將每個月按照月份分配好一個天數。

****************************/
void cal::Setyear(int **year)
{
	//開闢空間
	int gap_year = date.Get_year();
	int i = 0;
	int j = 0;
	for (i = 0; i < 8; i = i + 2)
	{
		year[i] = (int *)malloc(sizeof(int)* 32);
	}
	year[7] = (int *)malloc(sizeof(int)* 32);
	year[9] = (int *)malloc(sizeof(int)* 32);
	year[11] = (int *)malloc(sizeof(int)* 32);
	if ((((gap_year % 100) != 0) && ((gap_year) % 4 == 0)) || ((gap_year % 400) == 0))
	{
		year[1] = (int *)malloc(sizeof(int)* 30);
	}
	else
	{
		year[1] = (int *)malloc(sizeof(int)* 29);
	}
	year[3] = (int *)malloc(sizeof(int)* 31);
	year[5] = (int *)malloc(sizeof(int)* 31);
	year[8] = (int *)malloc(sizeof(int)* 31);
	year[10] = (int *)malloc(sizeof(int)* 31);

	//對內容初始化

}

/***************************

這個函式是用來初始化year1的,
將天數按照月份從小到大排序放入

****************************/
void cal::Inityear1(int ** year)

{
		//開闢空間
		int gap_year = date.Get_year();
		int i = 0;
		int j = 0;
		//對內容初始化

		for (i = 0; i < 12; i++)
		{
			if (i == 0 || i == 2 || i == 4 || i == 6 || i == 7 || i == 9 || i == 11)
			{
				for (j = 0; j < 32; j++)
				{
					if (j == 0)
					{
						year[i][0] = 31;
						continue;
					}
					year[i][j] = j;
				}
			}
			else if (i == 3 || i == 5 || i == 8 || i == 10)
			{
				for (j = 0; j < 31; j++)
				{
					if (j == 0)
					{
						year[i][0] = 30;
						continue;
					}
					year[i][j] = j;
				}
			}
			else if (i == 1)
			{
				if ((((gap_year % 100) != 0) && ((gap_year) % 4 == 0)) || ((gap_year % 400) == 0))
				{
					for (j = 0; j < 30; j++)
					{
						if (j == 0)
						{
							year[i][0] = 29;
							continue;
						}
						year[i][j] = j;
					}
				}
				else
				{
					for (j = 0; j < 29; j++)
					{
						if (j == 0)
						{
							year[i][0] = 28;
							continue;
						}
						year[i][j] = j;
					}
				}
			}
		}
}
/***************************

這個函式是用來初始化year1的,
將天數按照整年從小到大排序放入

****************************/
void cal::Inityear2(int **year)
{
	int i = 0;
	int j = 0;
	int count = 0;
	int temp = 0;
	for (i = 0; i < 12; i++)
	{
		temp = year[i][0];
		for (j = 1; j < temp + 1; j++)
		{
			count++;
			year2[i][j] = count;
		}
	}
}
/***************************

這個函式是用來初始化 year1,year2的

****************************/
void cal::Setinfo()
{
	Setyear(year1);
	Inityear1(year1);
	Setyear(year2);
	Inityear1(year2);
	Inityear2(year2);
}
/***************************

這個函式是用來列印year1的

****************************/
void cal::PrintCal()
{
	int i = 0;
	int j = 0;
	int temp = 0;
	int count = 0;
	int w = 0;
	for (i = 0; i < 12; i++)
	{

		count = 0;
		temp = year1[i][0];
		w = cal::Zeller(date.Get_year(), i + 1, 1);
		cout << "			     " << i + 1 << "月" << endl << endl;
		cout << "   日   一   二   三   四   五   六" << endl;

		for (j = 0; j < w; j++)
		{
			count++;
			cout << "     ";
		}
		for (j = 1; j < temp + 1; j++)
		{
			count++;
			cout.width(5);
			cout << year1[i][j];


			if (count % 7 == 0)
			{
				cout << endl;
			}
		}
		cout << endl << endl;
	}
}
/***************************

這個函式是用來列印year2的

****************************/
void cal::PrintCal_()
{
	int i = 0;
	int j = 0;
	int temp = 0;
	int count = 0;
	int w = 0;
	for (i = 0; i < 12; i++)
	{

		count = 0;
		temp = year2[i][0];
		w = cal::Zeller(date.Get_year(), i + 1, 1);
		cout<<"			     "<<i+1<<"月"<<endl<<endl;
		cout << "   日   一   二   三   四   五   六" << endl;

		for (j = 0; j < w; j++)
		{
			count++;
			cout<<"     ";
		}
		for (j = 1; j < temp + 1; j++)
		{
			count++;
			cout.width(5);
				cout << year2[i][j];
			
			
			if (count % 7 == 0)
			{
				cout << endl;
			}
		}
		cout << endl << endl;
	}
}
/***************************

這個函式是用來計算每個月1號是
星期幾的,為列印函式提供方法。
注:本來是使用Zeller公式,然後
發現Zeller不穩定,所以使用了年
基類,月基類,日基類演算法。

****************************/
int cal:: Zeller(int a,int b, int c)
{

	int   e, f;
	double x, y;
	x = a;
	y = x / 4;
	e = (int)y;
	if (y == e)
	{
		e = 2;//e是年基數
	}
	else
	{
		e = 1;
	}
	if (e = 1)
	{
		switch (b)
		{
		case 1:
			b = 0;
			break;
		case 2:
			b = 3;
			break;
		case 3:
			b = 3;
			break;
		case 4:
			b = 6;
			break;
		case 5:
			b = 1;
			break;
		case 6:
			b = 4;
			break;
		case 7:
			b = 0;
			break;
		case 8:
			b = 3;
			break;
		case 9:
			b = 5;
			break;
		case 10:
			b = 0;
			break;
		case 11:
			b = 3;
			break;
		case 12:
			b = 5;
			break;
		}
	}
	else
	{
		switch (b)
		{
		case 1:
			b = 0;
			break;
		case 2:
			b = 3;
			break;
		case 3:
			b = 4;
			break;
		case 4:
			b = 0;
			break;
		case 5:
			b = 2;
			break;
		case 6:
			b = 5;
			break;
		case 7:
			b = 0;
			break;
		case 8:
			b = 3;
			break;
		case 9:
			b = 6;
			break;
		case 10:
			b = 1;
			break;
		case 11:
			b = 4;
			break;
		case 12:
			b = 6;
			break;
		}//b是月基數
	}
	f = (a + a / 4 + a / 400 - a / 100 - e + b + c) % 7;
	return f;
}
/***************************

這個函式是用來查詢 date所處
的是一年當中的哪一天

****************************/
int cal::FindDay()
{
	cout << date << "  " << year2[date.Get_month() - 1][date.Get_day()];
	return year2[date.Get_month() - 1][date.Get_day()];
}
/***************************

這個函式是用來過載後置++運算子
函式在內部使用了過載後的+號
提高了穩定性、安全性

****************************/
Day operator ++(Day &d, int)
{
	Day temp = d;
	d=d+1;
	return temp;
}
/***************************

這個函式是用來過載前置++運算子
函式在內部使用了過載後的+號
提高了穩定性、安全性

****************************/
Day &operator ++(Day &d)
{
	d = d+1;
	return d;
}
/***************************

這個函式是用來過載+號,當加完天
後,這個date如果不穩定,那麼就將
進行調整。這裡的不穩定是指_day大於
_month容量

****************************/
Day operator +(Day d1, int days)
{
	Day temp(d1);

	if (days < 0)
	{
		return temp - (0 - days);
	}
	
	temp._day = temp._day + days;

	while ((temp._day > temp._GetDaysOfMonth(temp._year, temp._month)))
	{
		
		temp._day = temp._day - temp._GetDaysOfMonth(temp._year, temp._month);
		temp._month = temp._month + 1;
		if (temp._month > 12)
		{
			temp._month = 1;
			temp._year++;
		}
	}
	return temp;
}
/***************************

這個函式是用來過載-號,當減完天
後,這個date如果不穩定,那麼就將
進行調整。這裡的不穩定是指_day小於
_month容量

****************************/
Day operator - (Day d1, int days)
{
	Day temp(d1);
	if (days < 0)
	{
		return temp + (0 - days);
	}
	Day day_t = temp._GetDaysOfMonth(temp._year, temp._month);
	temp._day = temp._day - days;
	while((temp._day < 0))
	{
		temp._day = temp._day + temp._GetDaysOfMonth(temp._year, temp._month);
		day_t = temp._GetDaysOfMonth(temp._year, temp._month);
		temp._month = temp._month - 1;

		if (temp._month < 1)
		{
			temp._month = 12;
			temp._year --;
		}
	}
	return temp + 1;
}
/***************************

這個函式是用來過載輸出運算子
將輸出改為符合可讀性原則的程式碼

****************************/
ostream & operator << (ostream &_cout, const Day &d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
/***************************

這個函式是用來過載賦值運算子
賦值運算子的返回值是形參變數
實現了連續賦值。

****************************/
Day  Day ::  operator =(Day d1)
{
	this->_year = d1._year;
	this->_month = d1._month;
	this->_day = d1._day;
	return *this;
}
/***************************

這個函式是用來過載判斷相等的

****************************/
bool operator == (const Day &d1,const Day &d2)
{
	if ((d1._year == d2._year) && (d1._month == d2._month) && (d1._day == d2._day))
	{
		return true;
	}
	return false;
}
/***************************

這個函式是用來過載判斷小於的

****************************/
bool operator <(const Day &d1,const Day &d2)
{
	if ((d1._year > d2._year) || ((d1._year == d2._year) && (d1._month > d2._month)) || ((d1._year ==  d2._year) && (d1._month == d2._month) && (d1._day > d2._day)))
	{
		return true;
	}
	return false;
}
/***************************

這個函式是用來過載判斷大於的

****************************/
bool operator >(const Day &d1,const Day &d2)
{
	if ((d1._year < d2._year) || ((d1._year == d2._year) && (d1._month < d2._month)) || ((d1._year ==  d2._year) && (d1._month == d2._month) && (d1._day < d2._day)))
	{
		return true;
	}
	return false;
}
/***************************

這個函式是用來過載判斷小於等於的

****************************/
bool operator <=(const Day &d1,const Day &d2)
{
	if (d1 < d2 || d1 == d2)
	{
		return true;
	}
	return false;
}
/***************************

這個函式是用來過載判斷大於等於的

****************************/
bool operator >=(const Day &d1,const Day &d2)
{
	if (d1 > d2 || d1 == d2)
	{
		return true;
	}
	return false;
}