C++ 自定义日期类实现日期的加减算法

#include<iostream>
using namespace std;
class Date{
private:
	int m_year,m_month,m_day;
	int m_totalDaysYear;
public:
	Date(int year=2001,int month=1,int day=1);
	~Date(){};
	Date(const Date & date);
	Date & operator=(const Date & date);

	int operator-(const Date &date);
	Date operator+(int days);
	int compare(const Date &date);
	void print();
	int getDaysofYear();
	int getRemainingDaysofYear();
	friend ostream & operator<<(ostream & out, const Date & date);
};
inline bool isLeapYear(int year ){
	if(year%4==0&&year%100!=0||year%400==0) return true;
	else return false;
}
Date::Date(int year,int month,int day):m_year(year),m_month(month),m_day(day){ 
	m_totalDaysYear=isLeapYear(m_year)?366:365;
}
Date::Date(const Date &date){
	m_year=date.m_year;
	m_month=date.m_month;
	m_day=date.m_day;
	m_totalDaysYear=date.m_totalDaysYear;
}
Date & Date::operator=(const Date & date){
	if(this==&date) return *this;
	m_year=date.m_year;
	m_month=date.m_month;
	m_day=date.m_day;
	m_totalDaysYear=date.m_totalDaysYear;

	return *this;
}
int Date::operator-(const Date &date){
	int num=0;
	Date bigDate,smallDate;
	int value=compare(date);
	if(value==1){
		bigDate=*this;
		smallDate=date;
	}else if(value==-1){
		bigDate=date;
		smallDate=*this;
	}else return 0;

	int yearGap=bigDate.m_year-smallDate.m_year;
	if(yearGap>=2){
		for(int i=smallDate.m_year+1;i<=bigDate.m_year-1;i++){
			if(isLeapYear(i)) num+=366;
			else num+=365;
		}
		num+=bigDate.getDaysofYear();
		num+=smallDate.getRemainingDaysofYear();
	}else if(bigDate.m_year-smallDate.m_year==1){
		num+=bigDate.getDaysofYear();
		num+=smallDate.getRemainingDaysofYear();
	}else{
		num+=bigDate.getDaysofYear();
		num-=smallDate.getDaysofYear();
	}

	if(value==1) return num;
	else return -num;
}
Date  Date::operator+(int days){
	int year=m_year,month,day;
	int remainings=getRemainingDaysofYear();
	if(days>remainings){
		days-=remainings;
		year++;
		int num=isLeapYear(year)?366:365;
		while(days>num){ // 找到相应的年份
			days-=num;
			year++;
			num=isLeapYear(year)?366:365;
		}	
	}
	int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	if(isLeapYear(year)) months[1]=29;
	month=m_month;
	if(days-(months[m_month-1]-m_day)>0){
		days-=months[m_month-1]-m_day;
		int i=m_month;
		for(;i<12;i++){// 找到相应的月份
			if(days-months[i]<0) break;
			days-=months[i];
		}
		month=i+1;
	}
	day=days;
	return Date(year,month,day);
}
int Date::compare(const Date &date){
	if(m_year>date.m_year){
		return 1;
	}else if(m_year<date.m_year){
		return -1;
	}else{
		if(m_month>date.m_month) return 1;
		else if(m_month<date.m_month) return -1;
		else{
			if(m_day>date.m_day) return 1;
			else if(m_day<date.m_day) return -1;
			else return 0;
		} 
	}
}


void Date::print(){
	cout<<m_year<<'\\'<<m_month<<'\\'<<m_day<<endl;
}
int Date::getDaysofYear(){
	int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	if(isLeapYear(m_year)) months[1]=29;
	int num=0;
	for(int i=0;i<m_month-1;i++){
		num+=months[i];
	}
	return num+m_day;
}
int Date::getRemainingDaysofYear(){
	return m_totalDaysYear-getDaysofYear();
}


ostream & operator<<(ostream & out, const Date & date){
	out<<date.m_year<<'\\'<<date.m_month<<'\\'<<date.m_day;
	return out;
}


int main(){
	Date d1(2012,1,20),d2(2014,1,12);
  Date d3(d2),d4;
  d4=d1;
  cout<<d1;
	int days=50;
	cout<<d1<<" - "<<d2<<" = "<<d1-d2<<" days "<<endl;
	return 0;
}

(1) 测试日期类成员函数,在主函数中列出菜单选项,可以完成日期加减比较等测试功能。 (2) 完善程序功能,在日期相加的菜单选项中增加日期加天数,结果为新日期日期家月份,结果为新日期,要考虑闰年情况。 (3) 完善程序功能,在日期相减的菜单选项中增加日期减天数,结果为新日期日期减月份,结果为新日期,要考虑闰年情况。 (4) 显示日期时增加显示星期及英文形式的月份的功能。 (5) 增加输入的甄别功能,即输入非法数据(如负数、日期超过31天、时间超过24小时等情况)的识别显示功能。 (1) 仿照日期类编写时间类CTime_t,可以完成时间的设置、运算、比较等功能。 (2) 增加时间的输入功能,既可以选择输入格式,可以输入hh:mm:ss格式的信息。 (3) 增加时间的输出格式,可以输出12小时的时间格式。 (4) 编写时间和日期的派生类CDati,完成日期与时间的联合设置、运算、比较等功能,要求该派生类可以完成:日期时间加天数或时间等于新的日期时间,日期时间减天数或等于新的日期时间,两个日期时间相减等于天数或时间等工作,在程序中考虑闰年等具体情况,并重载各种运算符。 (5) 增加输入的甄别功能,即输入非法数据,即输入非法数据(如负数、日期超过31天、时间超过24小时等情况)的识别显示功能。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值