main.cpp
#include "Date.h"
#pragma warning(disable:4996)
//这个函数用于自测,实现一个功能可以试验一下
void Test()
{
Date d1(2022,12,9);
Date d2(d1);
Date d3(1997, 11, 18);
//if ((d1 == d2))
// cout << "真" << endl;
//else
// cout << "假" << endl;
//if ((d1 != d2))
// cout << "真" << endl;
//else
// cout << "假" << endl;
//if ((d1 == d3))
// cout << "真" << endl;
//else
// cout << "假" << endl;
//if ((d2 != d3))
// cout << "真" << endl;
//else
// cout << "假" << endl;
Date d4 = d1 + 1;
d4.Print();
}
//主菜单, 用于调用日期计算
void menu()
{
const char* WeekDays[] = { "周一","周二" ,"周三" ,"周四" ,"周五" ,"周六" ,"周日" };
Date d1, d2;
int option = 0;
int day = 0;
do
{
cout << "***************************************" << endl;
cout << " 1. 日期加 / 减天数 2.日期减日期 " << endl;
cout << "3. 日期->周几 -1. 退出" << endl;
cout << "***************************************" << endl;
cout << "请输入选项: ";
cin >> option;
switch (option)
{
case 1:
cout << "请输入日期和天数(如果要减,请输入-号)";
cin >> d1 >> day;
cout << "结果是:" << d1 + day << endl;
break;
case 2:
cout << "请输入两个日期:";
cin >> d1 >> d2;
cout << "两个日期相差天数" << d1 - d2 << endl;
break;
case 3:
cout << "请输入日期: ";
cin >> d1;
Date option(1, 1, 1);
int n = option - d1; // 这是相差的天数
//菜单是要多次循环的, 所以用weekday累计计算
int weekday = 0;
weekday += n;
cout << "这个日子是: ";
cout << WeekDays[weekday%7] << endl;
break;
}
} while (option!=-1);
}
int main()
{
menu();
return 0;
}
Date.cpp
#include "Date.h"
bool IsLeapYear(int year)
{
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
return true;
else
return false;
}
void Date:: Print() const
{
cout << _year << "/" << _month << "/" << _day << endl;
}
bool Date::operator==(const Date& d) const
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
bool Date::operator!=(const Date& d)const
{
return !(*this == d);
}
bool Date::operator>(const Date& d)const
{
return _year > d._year
|| (_year == d._year && _month > d._month)
|| (_year == d._year && _month == d._month && _day>d._day);
}
bool Date::operator>=(const Date& d)const
{
return (*this > d) || (*this == d);
}
bool Date::operator<(const Date& d)const
{
return !(*this >= d);
}
bool Date::operator<=(const Date& d)const
{
return !(*this > d);
}
Date Date::operator+(int day) const
{
Date ret(*this);
ret._day += day;
while (ret._day > GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if (ret._month > 12)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
Date& Date::operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
return *this;
}
Date& Date::operator++()
{
_day += 1;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
return *this;
}
Date Date::operator++(int)
{
Date ret(*this);
ret._day += 1;
while (ret._day > GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if (ret._month > 12)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
Date Date::operator-(int day)const
{
Date ret = *this;
ret -= day;
return ret;
}
Date& Date::operator-=(int day)
{
if (day < 0)
return (*this += day);
_day -= day;
while (_day < 0)
{
--_month;
if (_month < 1)
{
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
Date& Date::operator--() //前置
{
_day -= 1;
while (_day < 0)
{
--_month;
if (_month < 1)
{
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
Date Date::operator--(int) // 后置
{
Date ret(*this);
ret._day -= 1;
while (ret._day < 0)
{
--_month;
if (_month < 1)
{
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
int Date::operator-(const Date& d)
{
Date min(*this);
Date max(d);
int flag = 1;
if (min > max)
{
max = *this;
min = d;
flag = -1;
}
int cnt = 0;
while (min < max)
{
++min;
++cnt;
}
return cnt * flag;
}
// 日期 - 日期 返回天数 ( 另一种日期相减, 全部转换成天数)
//int operator-(const Date& d)
//{
// //先按照平年计算天数, 年*365 + 本身天数
// int day1 = d._day + 365 * d._year;
// int day2 = this->_day + 365 * this->_year;
//
// //如果是闰年就加1(2月份多一天)
// if (IsLeapYear(this->_year))
// {
// day2 += 1;
// }
// if (IsLeapYear(d._year))
// {
// day1 += 1;
// }
//
// //累加每个月的天数
// for (int i = 1; i < d._month; i++)
// {
// day1 += GetMonthDay(d._year, i);
// }
//
//
// for (int i = 1; i < this->_month; i++)
// {
// day2 += GetMonthDay(this->_year, i);
// }
//
//
//
// return day2 - day1;
//}
Date.h
#include<iostream>
#include <assert.h>
using namespace std;
bool IsLeapYear(int year);
class Date
{
// 友元函数 -- 这个函数内部可以使用Date对象访问私有保护成员
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);
public:
//获取某年某月的天数
int GetMonthDay(int year, int month) const
{
//这里用Static是因为, 这个函数会频繁调用. 存在静态区会节省资源
static int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int day = days[month];
if (month == 2 && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
{
day = 29;
}
return day;
}
bool CheckDate()
{
if (_year >= 1
&& _month >= 1 && _month < 13
&& _day >= 1 && _day < GetMonthDay(_year, _month)
)
return true;
else
return false;
}
//全缺省构造函数
inline Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
if (!CheckDate())
cout << "构造函数出错, 请检查日期设置值是否正确。" << endl;
}
//拷贝构造函数
//Date(const Date& d1)
//{
// _year = d1._year;
// _month = d1._month;
// _day = d1._day;
//}
void Print() const;
bool operator==(const Date& d) const;
bool operator!=(const Date& d) const;
bool operator>(const Date& d) const;
bool operator>=(const Date& d) const;
bool operator<(const Date& d) const;
bool operator<=(const Date& d) const;
Date operator+(int day) const;
Date& operator+=(int day);
Date& operator++(); //前置
Date operator++(int); //后置, 利用返回值和新增一个int类型参数构成函数重载
Date operator-(int day)const;
Date& operator-=(int day);
Date& operator--();//前置
Date operator--(int);//后置
int operator-(const Date& d);
private:
int _year;
int _month;
int _day;
};
// 流插入重载
inline ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
// 流提取重载
inline istream& operator>>(istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
assert(d.CheckDate());
return in;
}