实现一个日期类
- 了解到类中的默认成员函数之后,我们可以自己实现一个简单的日期类,由于代码较多,在这篇博客里我只实现了日历类,日期类的实现后面会上链接
分析要实现的功能
1. 日期类
class Date
{
public:
//构造函数
Date(int year = 1900, int month = 1, int day = 1);
//拷贝构造,赋值,析构不需要实现,使用默认的就可以了
//运算符重载
Date operator+(int day); // 日期加上天数
Date operator-(int day); // 日期减去天数
Date& operator+=(int day); // 日期+=天数
Date& operator-=(int day); // 日期-=天数
Date& operator++(); //日期+1,前置++
Date operator++(int); //日期+1,后置++
Date& operator--(); // 日期-1,前置--
Date operator--(int) // 日期-1,后置--
bool operator<(const Date& d); // 日期比较(小于)
bool operator==(const Date& d); // 日期比较(等于)
bool operator<=(const Date& d); // 日期比较(小于等于)
bool operator>=(const Date& d); // 日期比较(大于等于)
bool operator!=(const Date& d); // 日期比较(不等于)
bool operator>(const Date& d); // 日期比较(大于)
int operator-(const Date& d); // 日期相差天数
private:
bool IsInvalidDate(); //判断输入是否合法
int getDay(int year, int month); // 获取某年某月的天数
// << 和 >> 的重载,使用友元函数
friend ostream& operator<<(ostream& _cout, const Date& d);
friend istream& operator>>(istream& _cin, Date& d);
};
2. 日历类
为了直观的展示,编写一个日历类
class Calendar
{
public:
//构造函数
Calendar(int year = 1900);
//判断是否是闰年
bool IsLeap(int year);
//得到当月天数
int GetDaysOfMonth(int year, int month);
//打印全年的日历
void PrintCalendar();
//打印表头
void PrintTitle(int m);
private:
int _year;
int _firstdayOfMonth;
int _totalYear = 0;
int _totalMonth = 0;
int _totalDay = 0;
};
日历功能实现
函数:Calendar(int year = 1900);
功能:构造函数,创建一个日历对象
思路:输入年份是否有效,若无效使用默认日期
Calendar(int year = 1900)
:_year(year)
{
if (_year < 1900)
{
_year = 1900;
}
}
函数:bool IsLeap(int year);
功能:判断是否是闰年
思路:能够被4,不能被100整除,或者能够被400整除,则为闰年
bool IsLeap(int year)
{
if ((0 == _year % 4) && (0 != _year % 100) || (0 == _year % 400))
{
return true;
}
return false;
}
函数:int GetDaysOfMonth(int year, int month);
功能:得到当月天数
思路:当为闰年时,2月份为29天
int GetDaysOfMonth(int year, int month)
{
int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 2 && IsLeap(year))
{
days[month] += 1;
}
return days[month];
}
函数:void PrintCalendar();
功能:打印全年日历
思路:1900年1月1日是周一为基准,先得到到当前输入年的天数,四年一闰,百年不闰,四百年再闰;再计算当前输入年每个月的天数,并且根据totalDay根据与7的关系,可以计算出每月1号是礼拜几,为周日的时候,_firstdayOfMonth应该为0;打印出日期,每遇到周六换行
void PrintCalendar()
{
//1900年是1月1号是周一为基准
for (int i = 1900; i < _year; i++) {
// 四年一闰, 百年不闰, 四百年再闰
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
_totalYear += 366;
}
else {
_totalYear += 365;
}
}
for (int i = 1; i <= 12; i++)
{
int days = GetDaysOfMonth(_year, i);
int day;
if (i == 1)
{
day = 0;
}
else
{
day = GetDaysOfMonth(_year, i - 1);
}
_totalMonth += day;
_totalDay = _totalYear + _totalMonth;
// totalDay根据与7的关系,可以计算出每月1号是礼拜几
_firstdayOfMonth = _totalDay % 7 + 1;
//为周日的时候,_firstdayOfMonth应该为0
_firstdayOfMonth = _firstdayOfMonth == 7 ? 0 : _firstdayOfMonth;
PrintTitle(i);
for (int j = 1; j <= _firstdayOfMonth; j++)
{
cout << setw(4) << " ";
}
for (int d = 1; d <= days; d++) {
cout << setw(4) << d;
// 每遇到礼拜六换行
if ((d + _totalDay) % 7 == 6) {
cout << endl;
}
}
cout << endl;
}
}
函数:void PrintTitle(int m);
功能:打印表头
void PrintTitle(int m)
{
cout << endl;
cout << " " << m << "月 " << endl;
cout << "-----------------------------" << endl;
cout << " 日 一 二 三 四 五 六 " << endl;
cout << "-----------------------------" << endl;
}
效果展示
- 下图是2020年全年的日历