日期加减运算符重载C++修改

本文介绍了一个C++日期操作类的实现细节,包括日期加减、转换等核心功能,并通过实例展示了如何使用该类进行日期计算。

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class CDate
{
 friend ostream &operator<<(ostream &os, const CDate &other);
public:
 CDate(int y = 0, int m = 0, int d = 0)
 {
  m_year = y;
  m_month = m;
  m_day = d;
 }
 bool IsLeapYear(int year); //判断是否是闰年
 int DateToOn(const CDate &other); //日期转换为从0年0月0日起的天数
 int MonthDay(int year, int month); //当前月份有几天
 CDate operator +(const CDate &other); //两个日期相加
 int operator -(const CDate &other); //两个日期相减的天数
 CDate operator +(int nday);  //当前日期加上nday天
 CDate operator -(int nday);  //当前日期减去nday天

private:
 int m_year;
 int m_month;
 int m_day;
};

bool CDate::IsLeapYear(int year)
{
 return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));
}

int CDate::DateToOn(const CDate &other)
{
 int sumday = 0;

 sumday = other.m_year * 365;

 for(int i = 1; i < other.m_year; ++i)
 {
  if(IsLeapYear(i))
  {
   sumday++;
  }
 }
 int sum_day;
 switch(other.m_month)  //计算本月一起共有多少天
 {
 case 1:
  sum_day = 0;
  break;
 case 2:
  sum_day = 31;
  break;
 case 3:
  sum_day = 59;
  break;
 case 4:
  sum_day = 90;
 case 5:
  sum_day = 120;
 case 6:
  sum_day = 151;
  break;
 case 7:
  sum_day = 181;
  break;
 case 8:
  sum_day = 212;
  break;
 case 9:
  sum_day = 243;
  break;
 case 10:
  sum_day = 273;
  break;
 case 11:
  sum_day = 304;
  break;
 case 12:
  sum_day = 334;
  break;
 default:
  printf("Date Error!!!/n");
 }
 sumday += sum_day;
 sumday += other.m_day;
 if(IsLeapYear(other.m_year) && other.m_month > 2)//当前年份是否是闰年
 {
  sumday ++;
 }
 return sumday;
}

int CDate::MonthDay(int year, int month)
{
 int curday = 0;
 bool leap = IsLeapYear(year);

 switch(month)
 {
 case 1:
 case 3:
 case 5:
 case 7:
 case 8:
 case 10:
 case 12:
  curday = 31;
  break;
 case 2:
  if(leap)
  {
   curday = 29;
  }
  else
  {
   curday = 28;
  }
  break;
 case 4:
 case 6:
 case 9:
  curday = 30;
  break;
 default:
  ;
 }
 return curday;
}

CDate CDate::operator+(const CDate &other)
{
 CDate temp;
 
 temp.m_year = this->m_year + other.m_year;
 temp.m_month = this->m_month + other.m_month;
 if(temp.m_month > 12)
 {
  temp.m_year ++;
  temp.m_month -= 12;
 }
 temp.m_day = this->m_day + other.m_day;
 if(temp.m_day > MonthDay(temp.m_year, temp.m_month)) //判断当前天数是否大于本月的天数
 {
  temp.m_month ++;
  temp.m_day -= MonthDay(temp.m_year, temp.m_month);
 }
 return temp;
}

int CDate::operator-(const CDate &other)
{
 int disDay = 0;
 
 disDay = abs(DateToOn(other) - DateToOn(*this)); //调用DateToOn函数计算日期之差
 return disDay;
}

CDate CDate::operator+(int nday)
{
 int days = nday;
 int nyear = days / 365;

 CDate temp(nyear,0,0); //构造一个nyear的临时对象

 days %= 365;
 for(int i=1; i<=nyear; ++i)//计算余下一年内剩多少天
 {
  if(IsLeapYear(i))
  {
   days--;
  }
 }

 if(days > 0 && days <=31) //判断几月几日
 {
  temp.m_month += 1;
  temp.m_day += days;
 }
 else if(days <= 59)
 {
  temp.m_month += 2;
  temp.m_day = days - 28;
 }
 else if(days <= 90)
 {
  temp.m_month += 3;
  temp.m_day = days - 59;
 }
 else if(days <= 120)
 {
  temp.m_month += 4;
  temp.m_day = days - 90;
 }
 else if(days <= 151)
 {
  temp.m_month += 5;
  temp.m_day = days - 120;
 }
 else if(days <= 181)
 {
  temp.m_month += 6;
  temp.m_day = days - 151;
 }
 else if (days <= 212)
 {
  temp.m_month += 7;
  temp.m_day = days - 181;
 }
 else if( days <= 243)
 {
  temp.m_month += 8;
  temp.m_day = days - 212;
 }
 else if (days <= 273)
 {
  temp.m_month += 9;
  temp.m_day = days - 243;
 }
 else if(days <= 304)
 {
  temp.m_month += 10;
  temp.m_day = days - 273;
 }
 else if (days <= 334)
 {
  temp.m_month += 11;
  temp.m_day = days - 304;
 }
 else
 {
  temp.m_month += 12;
  temp.m_day = days - 334;
 }
 
 CDate Dest = *this + temp; //调用两个年份相加运算符构造最终对象
 return Dest;
}

CDate CDate::operator-(int nday)
{
 int days = nday;
 int nyear = days / 365;
 int nd = 0;

 //构造一个this->m_year- nyear - 1, this->m_month  , this->m_day的临时对象
 CDate temp(this->m_year- nyear - 1, this->m_month, this->m_day );
 days %= 365;
 for(int i=1; i<=nyear; ++i)//计算余下一年内剩多少天
 {
  if(IsLeapYear(i))
  {
   days--;
  }
 }
 if(IsLeapYear(this->m_year- nyear - 1)) //判断多减去的那一年是否是闰年
 {
  nd = 366 - days;
 }
 else
 {
  nd = 365 - days;
 }
 CDate Dest = temp + nd; //调用加一个整形天数运算符重载函数计算最终CDate对象
 return Dest;
}

ostream &operator<<(ostream &os, const CDate &other)
{
 os << other.m_year << "--" << other.m_month << "--" << other.m_day;
 return os;
}

int main()
{
 CDate date1(1990, 5, 2);
 
 cout << "The first date object is :" << date1 << endl;
 cout << "The days between (0, 0, 0 ) and first date has :"
  <<date1.DateToOn(date1) << " days" << endl;
 
 CDate date2(1988, 4, 6);
 cout << "The second date object is :" << date2 << endl;
 cout << "The first date +  second date is : " << date1 + date2 << endl;
 cout << "The first date -  second date has: " << date1 - date2 << " days" <<endl;
 cout << "After The first date2 + 726 days the date is :" << date2 + 726 << endl;
 cout << "After The first date - 726 days the date is :" << date1 - 726 << endl;
 return 0;
}
/*
The first date object is :1990--5--2
The days between (0, 0, 0 ) and first date has :726985 days
The second date object is :1988--4--6
The first date +  second date is : 3978--9--8
The first date -  second date has: 726 days
After The first date2 + 726 days the date is :1990--5--2
After The first date - 726 days the date is :1988--6--7
请按任意键继续. . .

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值