一个比较完善的日期类Date(一)

实现一个日期类

  • 了解到类中的默认成员函数之后,我们可以自己实现一个简单的日期类,由于代码较多,在这篇博客里我只实现了日历类,日期类的实现后面会上链接
分析要实现的功能
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年全年的日历
    2020
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值