日期类——日期计算器

来源:互联网 发布:java怎么学才能学得好 编辑:程序博客网 时间:2024/06/05 09:27

日期计算器的编写

想要完成日期计算器其实只要考虑完成两个工作就可以了

  • 1,给定一个日期加上或减去一个天数所得到的日期,换句话说就是这个日期前或后多少天是几号。
  • 2,给定两个日期,计算一下这两个日期之间相差多少天。

实现第一个工作时,如果是减去一个天数,例如 
给定2017 7 10

  • 第一种情况计算7天之前那就是2017-7-3。
  • 第二种情况计算28天之前2017-6-12。这种情况需要向前一月借天数减去28天来满足年月日合法。年月日合法作为循环结束的条件。
  • 第三种情况就是280天之前2016-10-3。需要向前一年月借天数减去280天来满足年月日合法,合法即结束。

与减去一个天数不同的加一个天数(即多少天以后)需要向当前月份的下一个月借天数减去目标天数来满足年月日合法。加减一个目标天数的实现思路个方法是一样的。个中细节请参考代码中的注释。 
实现第二个工作两个给定的目标日期相减时,主要有两种思路:

  • 第一种是规定一个基本日期让两个目标日期都从这着特定的日期开始加1,一直加到一直加到目标日期为止所得天数,所得到的天数做差取绝对值就是两个日期之间相差的天数。(这里可以复用重载+的代码 )。
  • 第二种是重载> 或 <运算符,首先找出较小(较前)的日期, 然后让较小的日期每次加1天直到加到较大日期为止。记录循环次数就是相差的天数。(这里需要重载== +=或++运算符)显然第二种方法更适用问题求解。

以下是实现代码

#include<iostream>
using namespace std;
//定义一个全局的数组用来存放一年中的每个月天数,二月默认是平年天数
int MonthDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//获取天数这个函数调用频繁所以设置成内联函数(典型的以空间换时间)
inline static int GetMonthDays(int year, int month)
{
if ((month == 2) && (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)))//判断是不是闰年
return 29;
else
return MonthDay[month];
}
//判断日期是否合法
inline static bool Islegal(int year, int month, int day)
{
if (((month >= 1) && (month <= 12)) && ((day >= 1) && (day <= GetMonthDays(year, month))))//这里一定要实时更新每年二月天数,否则有可能日期永远不合法
return true;
return false;
}

class Date
{
public:
Date(int year = 1990, int month = 1, int day = 1)//设置缺省参数
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}

friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);

bool operator>(const Date& d)
{
if (this->_year > d._year)
return true;
else if (this->_year == d._year&&this->_month > d._month)
return true;
else if (this->_year == d._year&&this->_month == d._month&&this->_day > d._day)
return true;
else
return false;
}
bool operator>=(const Date& d)
{
return *this > d || *this == d;
}
bool operator==(const Date& d)
{
return this->_year == d._year
&&this->_month == d._month
&&this->_day == d._day;
}
bool operator!=(const Date& d)
{
return this->_year != d._year
||this->_month != d._month
||this->_day != d._day;
}

Date operator-(int day)
{
if (day < 0)//进来先判断<0则是加上一个天数, 此时调用+
{
return *this + (-day);
}
Date tmp = *this;
tmp._day -= day;//当前月的天数减去目标天数后判断日期是否合法
while (!Islegal(tmp._year, tmp._month, tmp._day))
{//循环停止的条件是日期合法
tmp._month -= 1;//减到前一个月
if (tmp._month < 1)//判断一年是不是被减完了
{
tmp._year -= 1;//是的话就借前一年12月的天数
tmp._month = 12;
}
tmp._day += GetMonthDays(tmp._year, tmp._month);
}
return tmp;
}

Date operator+(int day)
{
if (day < 0)
{
return *this - (-day);
}
Date tmp = *this;
tmp._day += day;
while (!Islegal(tmp._year, tmp._month, tmp._day))
{//先减当前月天数
tmp._day -= GetMonthDays(tmp._year, tmp._month);
tmp._month += 1;
if (tmp._month > 12)
{//判断是否已经加到下一年了
tmp._year += 1;
tmp._month = 1;
}
}
return tmp;
}
Date& operator+=(int day)
{
*this = *this + day;
return *this;
}
Date& operator++()
{
*this = *this+1;
return *this;
}

int operator-(const Date& d)
{
Date min = *this;
Date max = d;
int count = 0;
int flag = -1;
if (*this>d)
{
max = *this;
min = d;
flag = 1;
}
while (min != max)
{
min+=1;
count++;
}
return count*flag;
}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "-" << d._month << "-" << d._day << endl;
return out;
}
istream& operator>>(istream& in, Date& d)
{
cout << "请输入日期:";
in >> d._year;
in >> d._month;
in >> d._day;
return in;
}

void menu()
{
while (1)
{
Date d1;
Date d2;
int input = 0;
int days = 0;
cout << "##################################" << endl;
cout << "1.日期相减 2.日期加减天数 3.退出" << endl;
cout << "##################################" << endl;
cout << "请选择>";
cin >> input;
switch (input)
{
case 1:
cin >> d1;
cin >> d2;
cout << "相差天数为:" << d2 - d1 << endl;
break;
case 2:
cin >> d1;
cout << "请输入一个天数(负数即向前推)";
cin >> days;
cout << days << "天后是" << d1 + days << endl;
break;
case 3:
return;
default:
cout << "选项不存在,请重新输入!" << endl;
break;
}
}
}

int main()
{
menu();
system("pause");
return 0;
}

简要总结

日期类不难就是得看你能不能想得通其中的思路,不要想得太复杂,其实写起来还是挺复杂的。但是许多代码是可以复用的,所以思考起来就不难了。关键还是看你怎么考虑这些问题了。

原创粉丝点击