Date.h
#pragma once
#include<iostream>
using namespace std;
class Date
{
private:
int _year;
int _month;
int _day;
public:
//构造函数
Date(int year=0, int month=1, int day=1);//缺省参数不能声名和定义都有,最好就声名有就可以了
void Print();
int GetMonthDay(int year, int day);//获得这月的天数
//运算符的重载
//所有类都是这样使用的
bool operator>(const Date& d);
//bool operator==(const Date& d);
Date& operator=(const Date& d);
//加天数
Date& operator+=(const int& day);
//减天数
Date& operator-=(const int& day);
Date& operator-(const int& day);
Date operator+(const int& day);
//++d
Date& operator++();//单目运算符,只有一个参数this,
//d++,增加一个参数原来占位,进行函数重载
Date operator++(int );
Date operator--(int);
Date& operator--();
//判断相等
bool operator==(const Date& d);
bool operator<(const Date& d);
bool operator>=(const Date& d);
//日期相减,
int operator-(const Date& d);
void PrintWeekDay();
};
Date.c
#include"Date.h"
int Date::GetMonthDay(int year, int month)//获得每个月的天数
{
//每次进来都要弄一下这数组,所以我们可以考虑弄成静态的,就不用每次进来都开辟数组,浪费空间
static int MonthDay[13] = {
0 ,31,28,31,30,31,30,31,31,30,31,30,31};//用数组来获得,默认2月28天,
//if ((year % 4 == 0 && year % 100 != 0) ||( year % 400 == 0)&&month==2)//可以先判断闰年
//{
// MonthDay[2] = 29;
//}
if (month == 2)//先判断是否为2月再选择是否要进入
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
MonthDay[2] = 29;
}
}
return MonthDay[month];
}
Date::Date(int year, int month , int day)//在外面引用加个::,构造函数
{
_year = year;
_month = month;
_day = day;
//检查一下日期是否合法
if (!(_year >= 0 && _month >= 0 && _month<13 && _day>0 && day <= GetMonthDay(year, month)))//整体取个非
{
cout << "非法日期" << endl;
Print();//类里面还可以访问成员函数
}
}
void Date::Print()
{
cout << _year <<"-" << _month <<"-" << _day << endl;
}
//>的重载
bool Date::operator>(const Date& d)
{
if (_year > d._year)
{
return true;
}
else if (_year == d._year && _month > d._month)
{
return true;
}
else if (_year == d._year && _month == d._month && _day > d._day)
{
return true;
}
else
{
return false;
}
}
Date& Date::operator+=(const int& day)//日期加天数,一直进位,天满了往月进位,月满了往年进位
{
_day += day;
while (_day >= GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month == 13)
{
_year++;
_month -= 12;
}
}
return *this;//返回的是Date类型的,所以返回*this就可以了,出了作用域还在,所以我们用引用返回
}
//不想改变原来的值
Date Date::operator+(const int& day)
{
Date ret(*this);//拷贝构造
//我们可以直接调用+=
ret += 100;
return ret;
}
Date Date::operator++(int)//后置++,返回之前的值,d++
{
Date ret(*this);//用拷贝构造接收之前的值
*this += 1;
return ret;
}
//推荐以后自定义类型++用前置,这样就可以不用做无用的拷贝构造
Date& Date::operator++()//前置++,返回之后的值
{
*this += 1;
return *this;
}
bool Date::operator==(const Date& d)//判断相等
{
return _year == d._year && _month == d._month && _day == d._day;
}
bool Date:: operator>=(const Date& d)
{
return *this > d || *this == d;
}
bool Date::operator<(const Date& d)
{
return !((*this) >= d);//小于是>=取反
}
//2022 1 17
// 30
// -13
//2021 12 18
//日期不合法就往月去借,月不够了就往年去借
Date& Date::operator-=(const int& day)
{
if (day < 0)
{
return *this += -day;
}
_day -= day;
while (_day < 1)
{
--_month;
if (_month == 0)//月也不合法
{
--_year;//年也减
_month = 12;//将他置为12
_day += GetMonthDay(_year, _month) ;
}
}
return *this;
}
Date& Date::operator-(const int& day)
{
Date ret(*this);
ret -= day;
return ret;
}
Date Date::operator--(int)//后置++,返回之前的值
{
*this -= 1;
Date ret(*this);
return ret;
}
//推荐以后自定义类型++用前置,这样就可以不用做无用的拷贝构造
Date& Date::operator--()//前置++,返回之后的值
{
*this -= 1;
return *this;
}
// 2022 9 1
//- 2022 1 17
// 0 8 -16
// 0 7 15
Date& Date::operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
//实现日期相减
int Date::operator-(const Date& d)//构成函数重载//d1-d2,我们不知道谁大谁小,所以大小是他们的绝对值,最后乘一个1或-1
{
//让小的那个天数加到大的天,有多少天就加多少天
Date less = *this;
Date more = d;
//一开始假设*this小也就是d1小减出来是一个负数
int flag = -1;
if (*this > d)
{
less = d;
more = *this;
flag = 1;
}
int day = 0;
while (!(less == more))
{
day++;
less++;
}
return day*flag;//前小后大,就是负的,后小前大就是正的
}
//获取今天是星期几
//1971的1月1日星期五,作为一个基准
void Date::PrintWeekDay()
{
const char* arr[7] = {
"星期1","星期2","星期3","星期4","星期5" ,"星期6","星期7" };
Date start(1900, 1, 1);
int count = *this - start;
cout << arr[count%7] << endl;
}
test.c
void Test1()
{
Date d1;
Date d2(2022, 1, 16);
d1.Print();
d2.Print();
Date d3(2022, 13, 15);
Date d4(2022, 2, 29);
Date d5(2020, 2, 29);
d5.Print();
d4.Print();
//想算一下100天后是多少天
d2 += 100;
d2.Print();
//实现d1+100;不改变d1的值
Date ret = d1 + 100;
ret.Print();
Date ret1 = d1++;//实现后置++,先使用再自增
Date ret2 = ++d1;
Date d6(2022, 1, 17);
d6 -= 30;
d6.Print();
Date k = d2 - 20;
k.Print();
Date d7(2022, 1, 12);
Date d8(2022, 1, 22);
int day = d7 - d8;
d7.PrintWeekDay();
}