要求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;
}