目录
一、设计思路
Date类的功能:
- Date类的赋值构造、拷贝构造
- Date日期的比较(==、!=、>、>=、<、<=)
- 计算Date日期与天数相加减得到的新日期
- Date日期的前置与后置自增自减
- Date日期与Date日期间相差的天数计算
- 查询当前Date日期是星期几
算法设计:
- 熟悉日期的基本性质,闰年的判断、每个月对应的天数
- 根据日期的性质可以计算出某个日期的总天数,根据某个日期的总天数可以得到某个日期是星期几
- 运算符重载,==、!=、>、>=、<、<= 这些运算符,只需要实现其中的部分,其他的可以利用已经重载过的运算符函数实现自身功能,+=、+、-=、-、++、--也是同理
- 公元 1 年 1 月 1 日默认是 周一,所以得到某个日期与公元 1 / 1 /1 的天数差值,就可以计算出周几
总结:本项目比较代码较简单,主要涉及类的构造与运算符重载,重点的算法设计是运算符重载的复用。
二、Date类的封装:Date.hpp
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <iostream>
#include <cassert>
#include <string>
class Time
{
public:
Time(int h = 0, int m = 0, int s = 0)
: _h(h), _m(m), _s(s)
{
assert(_h >= 0 && _m >= 0 && _s >= 0);
assert(_h < 24 && _m < 60 && _s < 60);
}
Time(const Time& time)
{
_h = time._h;
_m = time._m;
_s = time._s;
}
Time& operator=(const Time& time)
{
_h = time._h;
_m = time._m;
_s = time._s;
return *this;
}
private:
int _h, _m, _s;
};
class Date
{
public:
// 构造
Date(int year = 1, int mon = 1, int day = 1, Time time = Time())
: _year(year), _mon(mon), _day(day), _time(time)
{
assert(_year >= 1 && _mon >= 1 && _day >= 1);
assert(_mon <= 12 && _day <= Get_Mon_Days(_year, _mon));
}
Date(const Date& date)
{
_year = date._year;
_mon = date._mon;
_day = date._day;
_time = date._time;
}
Date& operator=(Date Date)
{
Swap(Date);
return *this;
}
// 日期类比较
bool operator==(const Date& Date)
{
if (_year == Date._year && _mon == Date._mon && _day == Date._day)
return true;
return false;
}
bool operator!=(const Date& Date)
{
return !(*this == Date);
}
bool operator>(const Date& Date)
{
if ((_year > Date._year) ||
(_year == Date._year && _mon > Date._mon) ||
(_year == Date._year && _mon == Date._mon && _day > Date._day))
return true;
return false;
}
bool operator>=(const Date& Date)
{
return (*this > Date || *this == Date);
}
bool operator<(const Date& Date)
{
return !(*this >= Date);
}
bool operator<=(const Date& Date)
{
return (*this < Date || *this == Date);
}
// 日期 ± 天数 = 日期
Date& operator+=(int days)
{
if (days < 0)
{
*this -= -days;
return *this;
}
_day += days;
while (_day > Get_Mon_Days(_year, _mon))
{
_day -= Get_Mon_Days(_year, _mon);
++_mon;
if (_mon == 13)
{
_mon = 1;
++_year;
}
}
return *this;
}
Date operator+(int days)
{
Date tmp(*this);
tmp += days;
return tmp;
}
Date& operator-=(int days)
{
if (days < 0)
{
*this += -days;
return *this;
}
_day -= days;
while (_day < 1)
{
--_mon;
if (_mon == 0)
{
_mon = 12;
--_year;
}
_day += Get_Mon_Days(_year, _mon);
}
return *this;
}
Date operator-(int days)
{
Date tmp(*this);
tmp -= days;
return tmp;
}
// 日期自增自减
Date& operator++()
{
return *this += 1;
}
Date operator++(int)
{
Date tmp(*this);
*this += 1;
return tmp;
}
Date& operator--()
{
return *this -= 1;
}
Date operator--(int)
{
Date tmp(*this);
*this -= 1;
return tmp;
}
// 日期 - 日期 = 天数
int operator-(const Date& date)
{
int flag = 1;
Date max(*this);
Date min(date);
if (*this < date)
{
max = date;
min = *this;
flag = -1;
}
int n = 0;
while (min != max)
{
++min;
++n;
}
return flag * n;
}
// 获取当期日期的总天数
int Get_Date_days()
{
int days = 0;
for (int i = 1; i < _year; ++i)
{
if (Leap_Year(i))
days += 366;
else
days += 365;
}
for (int i = 1; i < _mon; ++i)
{
days += Get_Mon_Days(_year, i);
}
days += _day;
return days;
}
// 查询当前日期对应的星期
std::string Search_Week()
{
int days = Get_Date_days();
int pos = days % 7;
std::string week[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
return week[pos];
}
// 输入输出,友元函数
friend std::ostream& operator<<(std::ostream& os, const Date& date);
friend std::istream& operator>>(std::istream& is, Date& date);
void Print()
{
printf("%04d-%02d-%02d %s\n", _year, _mon, _day, Search_Week().c_str());
}
private:
bool Leap_Year(int year)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return true;
return false;
}
int Get_Mon_Days(int year, int mon)
{
int month_days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (mon == 2 && Leap_Year(year))
return 29;
return month_days[mon];
}
void Swap(Date& Date)
{
std::swap(_year, Date._year);
std::swap(_mon, Date._mon);
std::swap(_day, Date._day);
std::swap(_time, Date._time);
}
private:
int _year, _mon, _day;
Time _time;
};
inline std::ostream& operator<<(std::ostream& os, const Date& date)
{
os << date._year << "-" << date._mon << "-" << date._day;
return os;
}
inline std::istream& operator>>(std::istream& is, Date& date)
{
is >> date._year >> date._mon >> date._day;
return is;
}
三、测试文件:main.cc
#define _CRT_SECURE_NO_WARNINGS 1
#include "Date.hpp"
using namespace std;
void Test1()
{
Date d1;
Date d2(2023, 8, 4);
Date d3(d2);
cout << "d1: " << d1 << endl;
cout << "d2: " << d2 << endl;
cout << "d3: " << d3 << endl;
cout << "d2.operator==(d1): " << d2.operator==(d1) << endl;
cout << "d2 != d1: " << (d2 != d1) << endl;
cout << "d2 == d3: " << (d2 == d3) << endl;
cout << "(d2 += 100) > d3: " << ((d2 + 100) > d3) << endl;
cout << "d2 > (d3 + 100): " << (d2 > (d3 + 100)) << endl;
cout << "d2 >= (d3 + 100 - 100): " << (d2 >= (d3 + 100 - 100)) << endl;
cout << endl;
}
void Test2()
{
Date d(2023, 8, 5);
(d + 100).Print();
(d + 1000).Print();
(d + 10000).Print();
(d + 100000).Print();
Date ret1(d + 100000);
cout << "ret1: " << ret1 << endl;
(d++).Print();
(++d).Print();
cout << endl;
(d--).Print();
(--d).Print();
(d - 100).Print();
(d - 1000).Print();
(d - 10000).Print();
(d - 100000).Print();
Date ret2(d - 100000);
cout << "ret2: " << ret2 << endl;
cout << "ret - ret2: " << (ret1 - ret2) << endl;
cout << endl;
}
void Test3()
{
cout << "*********************************" << endl;
cout << "* *" << endl;
cout << "* 1. 日期加减天数 *" << endl;
cout << "* 2. 日期减去日期 *" << endl;
cout << "* 3. 查询日期星期 *" << endl;
cout << "* 0. 退出 *" << endl;
cout << "* *" << endl;
cout << "*********************************" << endl;
int option;
do
{
cout << "请输入选项: ";
cin >> option;
if (option == 1)
{
Date d;
cout << "请输入日期: ";
cin >> d;
int days = 0;
cout << "请输入天数: ";
cin >> days;
(d + days).Print();
cout << endl;
}
else if (option == 2)
{
Date d1, d2;
cout << "请输入日期1: ";
cin >> d1;
cout << "请输入日期2: ";
cin >> d2;
cout << (d1 - d2) << endl << endl;
}
else if (option == 3)
{
Date d;
cout << "请输入日期: ";
cin >> d;
cout << d.Search_Week() << endl << endl;
}
else if (option == 0)
{
cout << "退出程序" << endl;
}
else
{
cout << "输入错误,请重新选择" << endl;
char buffer[1024];
fgets(buffer, sizeof(buffer), stdout);
}
} while (option);
}
int main()
{
//Test1(); // 测试构造与比较
//Test2(); // 测试日期运算
Test3();
return 0;
}