实现要求
1.可以任意构造一个日期对象
2.允许日期对象进行自加,自减(前&后)
3.日期对象前进/倒退任意天数可以得到另一个日期
4.两日期之间可以计算相差天数
5.允许两日期之间进行大小比较(>,<,>=,<=,==,!=)
6.可以得到任意输入某年某月的天数
需要编写的公有函数
1.默认构造函数
2.拷贝构造函数
3.析构函数
4.赋值重载函数
5.减法重载函数【2个】
6.加法重载函数
7.比较运算符重载函数【6个】
8.++重载函数【2个】,–重载函数【2个】
实现注意事项
1.闰年的处理(在涉及加减的地方需要时时牢记闰年要处理
2.月份天数可以通过一个命名空间内的数组实现,可以设元素数目为13的数组,可以使月份与索引相同
3.后++,后–需要备份后再运算
4.尽可能避免庞大的if-else if -else嵌套结构(可能会引起逻辑的混乱,或者在更复杂的项目里会使代码难以维护)
5.日期+天数,日期-天数可以先把天数直接运算到日期对象的号数上,再结合其他成员函数对对象的号数进行修改
6.成员函数实现时,相同的功能能调用则调用,无需重写一遍,这样做的目的:一旦运行结果出错,一般只需追溯到最终被调用的函数,可以使代码的错误源头减少,减轻查错负担。
7.根据日期计算星期的时候,需要注意历史原因导致的1982年10月4日之后,1982年10月15日之前的日期并不存在。且这两日期前后的星期计算方法略有差别。——蔡勒公式
Code
bool IsLeapYear(int year);
namespace Days {//申请13个的目的:月份=索引
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31 };
};
using namespace Days;
class Date
{
friend bool IsLeapYear(int year);
public:
int GetMonthDay(int year, int month) {
bool flag = IsLeapYear(year);
return (flag&& month==2)?days[month]+1:days[month];//闰年2月+1天
}
void DateShow() {
cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
void CountWeek(){
Date tmp1(1582,10,4);
Date tmp2(1582,10,15);
if((*this>tmp1)&&(*this<tmp2)){
cout<<(*this<tmp1)<<endl;
this->DateShow();
cout<<(*this>tmp1)<<endl;
cout<<"历史原因该日期不存在!"<<endl;
return;
}
int c,d,m,y,w;
d = this->_day;
m = this->_month;
y = this->_year;
if(m == 1 || m == 2){
m += 12;
--y;
}
c = y/100,y%=100;
w = (y + y/4 + c/4 -2*c + 13*(m+1)/5 + d - 1) % 7;
if(*this<=tmp1)
w += 3;
w = (w+7)%7;
cout<<_year<<"年"<<_month<<"月"<<_day<<"日";
switch(w){
case 0:cout<<":星期天"<<endl;break;
case 1:cout<<":星期一"<<endl;break;
case 2:cout<<":星期二"<<endl;break;
case 3:cout<<":星期三"<<endl;break;
case 4:cout<<":星期四"<<endl;break;
case 5:cout<<":星期五"<<endl;break;
case 6:cout<<":星期六"<<endl;break;
}
}
Date(int year = 1900, int month = 1, int day = 1) { //全缺省默认构造函数
_year = year;
_month = month;
_day = day;
}
Date(const Date &t) {// 拷贝构造函数
_year = t._year;
_month = t._month;
_day = t._day;
}
Date& operator=(const Date& d) {//赋值运算符重载
if (this != &d) {
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
~Date() {}
Date& operator+=(int day) {
*this = *this + day;
return *this;
}
Date operator+(int day) {
Date p(*this);
if (day < 0) {
p -= -day;
return p;
}
p._day += day;
while (p._day > GetMonthDay(p._year, p._month)) {
p._day -= GetMonthDay(p._year, p._month);
++p._month;
if (p._month == 13) {
p._month = 1;
++p._year;
}
}
return p;
}
Date operator-(int day) {
Date p(*this);//新对象
if (day < 0) {
p += -day;
return p;
}
p._day -= day;
int month = 0;
while (p._day <= 0) {
month = p._month == 1 ? 12 : p._month - 1;//月份为1则减到上一年12月
p._day += GetMonthDay(p._year, month);//加上上一月天数
--p._month;//月份倒退
if (p._month == 0) {//年份倒退
p._month = 12;
--p._year;
}
}
return p;
}
Date& operator-=(int day) {
*this = *this - day;
return *this;
}
Date& operator++() {
*this = *this + 1;
return *this;
}
Date operator++(int) {
Date tmp(*this);
*this += 1;
return tmp;
}
Date operator--(int) {
Date tmp(*this);
*this -= 1;
return tmp;
}
Date& operator--() {
*this -= 1;
return *this;
}
bool operator>(const Date& d) {
if (d._year > (*this)._year)
return false;
if (d._year < (*this)._year)
return true;
if (d._month > (*this)._month)//到达此处,说明年份一样
return false;
if (d._month < (*this)._month)
return true;
if (d._day > (*this)._day)//达到此处,说明月份一样
return false;
if (d._day < (*this)._day)
return true;
return false;
}
bool operator==(const Date& d) {
return d._year == (*this)._year &&
d._month == (*this)._month &&
d._day == (*this)._day;
}
inline bool operator >= (const Date& d) {
return *this > d || *this == d;
}
bool operator < (const Date& d) {
return !(*this >= d);//<的互斥函数为>=
}
bool operator <= (const Date& d) {
return !(*this > d);//<= 的互斥事件为>
}
bool operator != (const Date& d) {
return !((*this) == d);//!= 的互斥事件为 ==
}
int operator-(const Date& d) {
Date Min;
Date Max;
*this < d ? (Max = d, Min = *this) : (Max = *this, Min = d);
int res = 0;
while (Min < Max)
++res, ++Min;
return res;
}
private:
int _year;
int _month;
int _day;
};
bool IsLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0)//普通闰年
return true;
if (year % 400 == 0)//世纪闰年
return true;
return false;
}