实现日期类:日期+天数/日期-天数/根据日期算星期几

实现要求

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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值