今天我们尝试用C++来实现一下日期计算器,废话少说,发车!
1. 项目认识
这个是网上的日期计算表,我们可以看一下。
2.项目功能
类似于链接中的日期计算机,我们的小项目中也有其功能,我们可以通过天数来找到目标日期,可以计算两个不同日期的相差天数,也可以进行大小比较等。
3.项目实现
3.1****编写思路
对于日期表的创建,首先是要有日期的输入输出方法,然后创建不同的算法函数来实现有意义的日期计算,对于输入,输出,我们也要有合理性的判断,防止不切实际的现象发生。
3.2****步骤预览
- 创建头文件&源文件
- 初定义日期
- 算法实现
- 运行检查
3.3****代码实现
1.初定义日期
头文件: // 全缺省的构造函数 Date(int year = 1900, int month = 1, int day = 1); 源文件: Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; //if(this->CheckDate()) if (!CheckDate()) { cout << "非法日期->" << *this << endl; } }
2.算法头文件预览
3.计算月份(GetMonthDay)
月份计算是通用功能,写在头文件里是为了:复用、统一、防错、规范。
思路:我们在写的时候,首先考虑到月份的特殊性,比如大小月,闰年的情况;对于大小月,我们可以直接利用数组来具体选择;对于闰年,"四年一闰,百年不闰,四百年再闰",我们在代码书写时,要注意其中的逻辑关系,这是()的使用就很关键。
int GetMonthDay(int year, int month) { assert(month > 0 && month < 13); static int monthDayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { return 29; } else return monthDayArray[month]; }
4.输出打印(Print)
void Date::Print() const { cout << _year << "/"<<_month <<"/" << _day << endl; }
5.异常检查(CheckDate)
注意日期是否符合实际
bool Date::CheckDate() { if (_day<1 || _day>GetMonthDay(_year, _month) || _month < 1 || _month>12 ) { return false; } else return true; }
6."+="的实现
思路:当我们在加天数时,会存在多种情况,比如月份的跨越,年份的跨越,此外也会出现用户输出错误的问题,比如负数。
注意这里使用引用返回可以减少拷贝,提高效率。我们注意下后面使用引用的情况。
Date& Date::operator+=(int day) { if (day < 0) return *this -= -day; _day += day; while(_day > GetMonthDay(_year, _month)) { _month = _month + 1; if (_month == 13) { _month = 1; _year++; } _day -= GetMonthDay(_year, _month); } return *this; }
7."+"的实现
这里没有用引用返回,为什么呢?因为会出现野引用,我们要返回tmp的临时对象,tmp已经销毁。此外我们在return值时,也会犯下错误。
Date Date::operator+(int day) { Date tmp = *this; tmp += day; return tmp ; }8."-="的实现
思路:与"+="的情况相反,逻辑相同。
Date& Date::operator-=(int day) { if (day < 0) return *this += -day; _day -= day; while (_day <= 0) { _month = _month - 1; if (_month == 0) { _month = 12; --_year; } _day += GetMonthDay(_year, _month); } return *this; }
9."-"的实现
Date Date::operator-(int day) { Date tmp = *this; tmp -= day; return tmp;
10.前置"++"的实现
Date& Date::operator++() { *this+=1; return *this; }
11.后置"++"的实现
Date Date::operator++(int) { Date tmp = *this; *this += 1; return tmp; }这里详细介绍引用返回和传值返回的区别。
12.前置"--"的实现
Date& Date::operator--() { *this -= 1; return *this; }13.后置"--"的实现
Date Date::operator--(int) { Date tmp = *this; *this -= 1; return tmp; }14."=="的实现
bool Date::operator==(const Date& d) const { return _year == d._year && _day == d._day && _month == d._month; }15."!="的实现
bool Date::operator!=(const Date& d) const { return !(*this == d);
16."<"的实现
bool Date::operator<(const Date& d) const { if (_year < d._year) return true; if (_month < d._month) return true; if (_day < d._day) return true; return false; }17."<="的实现
bool Date::operator<=(const Date& d) const { return (*this == d || *this < d); }18.">"的实现
bool Date::operator>(const Date& d) const { return !(*this <= d); }19.">="的实现
bool Date::operator>=(const Date& d) const { return !(*this < d); }
20."-"的实现
思路:与"+"的情况相反,但逻辑上更加复杂,不光要注意月份与年份的跨越问题,我们更要判断日期相减的大小情况,这里我们便使用到flag来定义两种情况,来判断运算的正负结果。
int Date::operator-(const Date& d) const { Date max = *this; Date min = d; int flag = 1; if (*this < d) { max = d; min = *this; flag = -1; } int count = 0; while (min != max) { ++min; ++count; } return count * flag; }
21.输入输出的实现(友元函数介绍)
友元函数****是定义在类外部,但有权访问该类的 private /protected 成员的特殊函数。它不是类的成员函数,但被类 "授权" 了访问权限。
首先这里我们要明白为什么要使用友元函数?为什么不把函数包含在类中?这里在上一篇博客中我们详细介绍了,大家可以去看下https://blog.csdn.net/2602_95649725/article/details/160417849?fromshare=blogdetail&sharetype=blogdetail&sharerId=160417849&sharerefer=PC&sharesource=2602_95649725&sharefrom=from_link
https://blog.csdn.net/2602_95649725/article/details/160417849?fromshare=blogdetail&sharetype=blogdetail&sharerId=160417849&sharerefer=PC&sharesource=2602_95649725&sharefrom=from_link
friend ostream& operator<<(ostream& out, const Date& d); friend istream& operator>>(istream& in, Date& d); ostream& operator<<(ostream& out, const Date& d) { out << d._year << "年" << d._month << "月" << d._day << "日" << endl; return out; } istream& operator>>(istream& in, Date& d) { while (1) { cout << "请依次输入年月日:>"; in >> d._year >> d._month >> d._day; if (d.CheckDate()) { break; } else { cout << "非法日期,请重新输入!" << endl; } } return in; }
4.实例输出
5.gitee源码








