在程序猿眼中时间是一个很重要的概念(大部分强大的替身都与时间挂钩,jojo梗无端想象),日期作为时间的一种类型自然也不例外。偶尔,日期之间的计算也是不可避免的。运算时,很多人会在网上找到一些日期计算器,那么,日期计算器到底是怎么实现的呢?
接下来,就是我用初阶C++实现日期计算器的一种思路和代码。
目录
1.类的创建
注意: 获取某年某月的天数这个函数在之后经常用到。
//日期类
class Date
{
//公有
public:
// 获取某年某月的天数
int GetMonthDay(int year, int month)
{
//日期数组
int MonthDayarr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//判断闰年
if (2 == month && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
{
return MonthDayarr[2] + 1;
}
else
{
return MonthDayarr[month];
}
}
//全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
//检查日期是否合法
if (!(year >= 1
&& (month >= 1 && month <= 12)
&& (day >= 1 && day <= GetMonthDay(year, month))))
{
cout << "日期非法" << endl;
}
}
//析构函数
~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
2.拷贝构造函数
在日期类的使用中,可能需要将日期d1的值赋给d2,也就是相当于d1 = d2.
//日期类
class Date
{
//公有
public:
// 拷贝构造函数
// d2(d1)
Date(const Date& d) //d为d1的引用
{
_year = d._year; //把d1的year值赋给d2
_month = d._month;
_day = d._day;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d1(2022,1,1);
//用法
Date d3(d1); //初始化d3,值为d1
//与int a = b;类似
return 0;
}
3.'='运算符重载
运算符重载可以使自定义类型进行"+-*/="等操作
与构造拷贝相比,虽然都是将d1的值赋给d2的相关功能,但是因为'='运算符重载返回类型是"Date",所以能进行Date d3 = d2 = d1;这样的操作。
//日期类
class Date
{
//公有
public:
// =赋值运算符重载
// d2 = d1
Date& operator=(const Date& d) //返回类型为Date
{
_year = d._year;
_month = d._month;
_day = d._day;
return (*this); //this指针指向d2地址
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d1(2022,1,1);
Date d2(2022,1,2);
//用法1
d2 = d1; //把d1的值赋给d2
//用法2
Date d3 = d1; //初始化d3,值为d1
//与int a = b;类似
return 0;
}
4.‘==’ 与 ’!=‘运算符重载
‘==’ 与 ’!=‘运算符重载 是用来判断日期d1 与 日期d2是否相等,返回类型bool .
//日期类
class Date
{
//公有
public:
// ==运算符重载
bool operator==(const Date& d) //返回类型为bool
{
//年月日都相等返回true
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
// !=运算符重载
bool operator!=(const Date& d)
{
return !operator==(d); //直接返回!operator==(d)偷懒
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d1(2022,1,1);
Date d2(2022,1,2);
//用法
if (d1 == d2)
cout << "d1==d2" << endl;
else
cout << "d1!=d2" << endl;
return 0;
}
5.’<' 与 ‘>'运算符重载
- d1 > d2,首先判断两者year的大小,
- 当year1 > year2,直接确定d1>d2返回true;
- year1 < year2,则d1<d2返回false;
- 当year1 == year2时,再比较month大小......
- d1 < d2, 与"d1 > d2"差不多思路。
//日期类
class Date
{
//公有
public:
// >运算符重载
bool operator>(const Date& d)
{
if (_year > d._year)
return true;
else if (_year < d._year)
return false;
else
{
if (_month > d._month)
return true;
else if (_month < d._month)
return false;
else
{
if (_day > d._day)
return true;
else
return false;
}
}
}
// <运算符重载
bool operator<(const Date& d)
{
if (_year < d._year)
return true;
else if (_year > d._year)
return false;
else
{
if (_month < d._month)
return true;
else if (_month > d._month)
return false;
else
{
if (_day < d._day)
return true;
else
return false;
}
}
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
6.<= 与 >=运算符重载
需要与上面的==,<, > 运算符重载结合使用
//日期类
class Date
{
//公有
public:
// >=运算符重载
bool operator>=(const Date& d)
{
return operator>(d) || operator==(d);
}
// <=运算符重载
bool operator<=(const Date& d)
{
return operator<(d) || operator==(d);
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
7.日期+=天数
//日期类
class Date
{
//公有
public:
// 日期+=天数
Date& operator+=(int day)
{
_day += day; //_day加上要加的天数
while (_day > GetMonthDay(_year, _month)) //加完后,如果_day大于当月天数,进入循环
{
//_day减去当月天数,_month++
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)//如果_month大于12,则_month 变为1,_year++
{
_month = 1;
_year++;
}
}
return *this;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
举例:2022.11.28 + 70
- _day+60 2022.11.98
- 加完后,_day大于当月天数,进入循环
- _day减去当月天数,_month++ 2022.12.40
- _day依旧大于当月天数,进入循环
- _day减去当月天数,_month++ 2022.13.9
- _month大于12 ,则_month 变为1,_year++ 2023.1.9
完成
8.日期+天数
与+=不同的是,+没有改变原来日期的值,而是创建一个临时变量ret储存日期+天数后的值,再返回ret.
//日期类
class Date
{
//公有
public:
// 日期+天数
Date operator+(int day)
{
Date ret(*this);
ret += day; //运用到上面的+=运算符重载
return ret;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
9.日期-=天数
思路与+=相似,只不过是反过来计算的。
//日期类
class Date
{
//公有
public:
// 日期-=天数
Date& operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
_month--;
if (_month < 1)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
10.日期-天数
思路与日期+天数相似
//日期类
class Date
{
//公有
public:
// 日期-天数
Date operator-(int day)
{
Date ret(*this);
ret -= day; //运用到上面的-=运算符重载
return ret;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
11.前置++与后置++
- 前置++:返回+1之后的结果
- 后置++:
- 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
- C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递
- 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this+1
- 而temp是临时对象,因此只能以值的方式返回,不能返回引用
//日期类
class Date
{
//公有
public:
// 前置++
Date& operator++()
{
*this += 1;
return *this;
}
// 后置++
Date operator++(int)
{
Date ret(*this);
ret += 1;
return ret;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
12.前置--与后置--
思路与前置++,后置++相似
//日期类
class Date
{
//公有
public:
// 前置--
Date& operator--()
{
*this -= 1;
return *this;
}
// 后置--
Date operator--(int)
{
Date ret(*this);
ret -= 1;
return ret;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
13.日期-日期
d1 - d2 ,
- d1 > d2时,tmp--,count++直到tmp == d2,跳出循环,返回count
- d1 < d2时,tmp++,count++直到tmp == d2,跳出循环,返回count
//日期类
class Date
{
//公有
public:
//日期-日期
int operator-(const Date& d)//与日期-天数重载
{
int count = 0;
Date tmp(*this); //原日期不改变
if ((*this) > d)
{
while (tmp != d)
{
count++;
--tmp;
}
}
else
{
while (tmp != d)
{
count++;
++tmp;
}
}
return count;
}
//私有
private:
int _year;//年
int _month;//月
int _day;//日
};
以上就是全部内容啦!拜~
源码:
#include<iostream>
using namespace std;
//日期类
class Date
{
public:
// 获取某年某月的天数
int GetMonthDay(int year, int month)
{
//日期数组
int MonthDayarr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//判断闰年
if (2 == month && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
{
return MonthDayarr[2] + 1;
}
else
{
return MonthDayarr[month];
}
}
// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
//检查日期是否合法
if (!(year >= 1
&& (month >= 1 && month <= 12)
&& (day >= 1 && day <= GetMonthDay(year, month))))
{
cout << "日期非法" << endl;
}
}
// 拷贝构造函数
// d2(d1)
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d1 -> d2.operator=(&d2, d1)
Date& operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return (*this);
}
// ==运算符重载
bool operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
// >运算符重载
bool operator>(const Date& d)
{
if (_year > d._year)
return true;
else if (_year < d._year)
return false;
else
{
if (_month > d._month)
return true;
else if (_month < d._month)
return false;
else
{
if (_day > d._day)
return true;
else
return false;
}
}
}
// >=运算符重载
bool operator>=(const Date& d)
{
return operator>(d) || operator==(d);
}
// <运算符重载
bool operator<(const Date& d)
{
if (_year < d._year)
return true;
else if (_year > d._year)
return false;
else
{
if (_month < d._month)
return true;
else if (_month > d._month)
return false;
else
{
if (_day < d._day)
return true;
else
return false;
}
}
}
// <=运算符重载
bool operator<=(const Date& d)
{
return operator<(d) || operator==(d);
}
// !=运算符重载
bool operator!=(const Date& d)
{
return !operator==(d);
}
// 日期+=天数
Date& operator+=(int day)
{
_day += day; //_day加上要加的天数
while (_day > GetMonthDay(_year, _month)) //加完后,如果_day大于当月天数,进入循环
{
//_day减去当月天数,_month++
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)//如果_month大于12,则_year++
{
_month = 1;
_year++;
}
}
return *this;
}
// 日期+天数
Date operator+(int day)
{
Date ret(*this);
ret += day;
return ret;
}
// 日期-=天数
Date& operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
_month--;
if (_month < 1)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
// 日期-天数
Date operator-(int day)
{
Date ret(*this);
ret -= day;
return ret;
}
// 前置++
Date& operator++()
{
*this += 1;
return *this;
}
// 后置++
Date operator++(int)
{
Date ret(*this);
ret += 1;
return ret;
}
// 前置--
Date& operator--()
{
*this -= 1;
return *this;
}
// 后置--
Date operator--(int)
{
Date ret(*this);
ret -= 1;
return ret;
}
//日期-日期
int operator-(const Date& d)//与日期-天数重载
{
int count = 0;
Date tmp(*this); //原日期不改变
if ((*this) > d)
{
while (tmp != d)
{
count++;
--tmp;
}
}
else
{
while (tmp != d)
{
count++;
++tmp;
}
}
return count;
}
// 析构函数
~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
private:
int _year;
int _month;
int _day;
};