c++實現簡單日期類
阿新 • • 發佈:2018-12-20
概要
下面這一大塊程式碼主要練習了 運算子過載。設定了一個日期類。如有問題請看註釋。
//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; }