• 【C++】日期类实现,与日期计算相关OJ题



    在软件开发中,处理日期是一项常见的任务。为了方便地操作日期,我们可以使用C++编程语言来创建一个简单的日期类。在本文中,我们将介绍如何使用C++实现一个基本的日期类,包括日期的加减、大小比较等功能。

    日期类的设计

    下面是日期类的基本实现代码:

    #pragma once
    #include
    using namespace std;
    
    class Date {
    public:
        // 获取某年某月的天数
        int GetMonthDay(const int year, const int month);
        // 构造函数
        Date(int year = 1900, int month = 1, int day = 1);
        // 拷贝构造函数
        Date(const Date& d);
        // 析构函数
        ~Date();
        // 打印日期
        void print()const;
        // 赋值运算符重载
        Date& operator=(const Date& d);
        // +=运算符重载
        Date& operator+=(const int day);
        // +运算符重载
        Date operator+(const int day);
        // -=运算符重载
        Date& operator-=(int day);
        // -运算符重载
        Date operator-(int day);
        // 计算两个日期之间的天数差
        int operator-(const Date& d) const;
        // ++前置运算符重载
        Date& operator++();
        // ++后置运算符重载
        Date operator++(int);
        // --前置运算符重载
        Date& operator--();
        // --后置运算符重载
        Date operator--(int);
        // 大于运算符重载
        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;
        // 地址运算符重载
        const Date* operator & () const;
        // 输出流运算符重载
        friend ostream& operator << (ostream& out, const Date& d);
        // 输入流运算符重载
        friend istream& operator >> (istream& in, Date& d);
    
    private:
        int _year;  // 年
        int _month;  // 月
        int _day;  // 日
    };
    
    // 获取某年某月的天数
    int Date::GetMonthDay(const int year, const int month) {
        int monthDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (2 == month && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
            return 29;
        }
        return monthDay[month];
    }
    
    // 构造函数
    Date::Date(int year, int month, int day) {
        if ((year < 1) || (month < 1) || (month > 12) || (day < 1) || (day > GetMonthDay(year, month))) {
            cout << "非法日期:" << endl;
        }
        _year = year;
        _month = month;
        _day = day;
    }
    
    // 拷贝构造函数
    Date::Date(const Date& d) {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    
    // 析构函数
    Date::~Date() {
        _year = 1900;
        _month = 1;
        _day = 1;
    }
    
    // 打印日期
    void Date::print()const {
        cout << _year << "/" << _month << "/" << _day << endl;
    }
    
    // 赋值运算符重载
    Date& Date::operator=(const Date& d) {
        if (this != &d) {
            _day = d._day;
            _month = d._month;
            _year = d._year;
        }
        return *this;
    }
    
    // +=运算符重载
    Date& Date::operator+=(const int day) {
        _day += day;
        while (_day > GetMonthDay(_year, _month)) {
            _day -= GetMonthDay(_year, _month);
            ++_month;
            if (_month == 13) {
                ++_year;
                _month = 1;
            }
        }
        return *this;
    }
    
    // +运算符重载
    Date Date::operator+(const int day) {
        Date tmp(*this);
        tmp += day;
        return tmp;
    }
    
    // -=运算符重载
    Date& Date::operator-=(int day) {
        _day -= day;
        while (_day < 0) {
            --_month;
            if (_month == 0) {
                --_year;
                _month = 12;
            }
            _day += GetMonthDay(_year, _month);
        }
        return *this;
    }
    
    // -运算符重载
    Date Date::operator-(int day) {
        Date tmp(*this);
        tmp -= day;
        return tmp;
    }
    
    // 计算两个日期之间的天数差
    int Date::operator-(const Date& d) const {
        Date BigDate = *this;
        Date SmallDate = d;
        if (SmallDate > BigDate) {
            BigDate = d;
            SmallDate = *this;
        }
        int count = 0;
        while (SmallDate != BigDate) {
            ++SmallDate;
            ++count;
        }
        return count;
    }
    
    // ++前置运算符重载
    Date& Date::operator++() {
        *this += 1;
        return *this;
    }
    
    // ++后置运算符重载
    Date Date::operator++(int) {
        Date tmp(*this);
        *this += 1;
        return tmp;
    }
    
    // --前置运算符重载
    Date& Date::operator--() {
        *this -= 1;
        return *this;
    }
    
    // --后置运算符重载
    Date Date::operator--(int) {
        Date tmp(*this);
        *this -= 1;
        return tmp;
    }
    
    // 大于运算符重载
    bool Date::operator>(const Date& d) const {
        if (_year > d._year || (_year == d._year && _month > d._month) || (_year == d._year && _month == d._month && _day > d._day)) {
            return true;
        }
        return false;
    }
    
    // 等于运算符重载
    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) || (*this == d);
    }
    
    // 小于运算符重载
    bool Date::operator < (const Date& d) const {
        return !(*this >= d);
    }
    
    // 小于等于运算符重载
    bool Date::operator <= (const Date& d) const {
        return !(*this > d);
    }
    
    // 不等于运算符重载
    bool Date::operator != (const Date& d) const {
        return !(*this == d);
    }
    
    // 地址运算符重载
    const Date* Date::operator & () const {
        return this;
    }
    
    // 输出流运算符重载
    ostream& operator << (ostream& out, const Date& d) {
        out << d._year << "/" << d._month << "/" << d._day;
        return out;
    }
    
    // 输入流运算符重载
    istream& operator >> (istream& in, Date& d) {
        in >> d._year;
        in >> d._month;
        in >> d._day;
        return in;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244

    上面的代码实现了日期类的基本功能,包括构造函数、加减运算符重载、比较运算符重载、输入输出流运算符重载等。
    下面是主函数用于测试代码功能:

    int main() {
        // 创建日期对象并打印
        Date d1(2023, 11, 13);
        cout << "日期1:";
        d1.print();
    
        // 拷贝构造函数测试
        Date d2(d1);
        cout << "日期2(拷贝构造):";
        d2.print();
    
        // 赋值运算符重载测试
        Date d3 = d1;
        cout << "日期3(赋值运算符重载):";
        d3.print();
    
        // += 运算符重载测试
        d1 += 10;
        cout << "日期1(+=运算符重载后):";
        d1.print();
    
        // + 运算符重载测试
        Date d4 = d2 + 5;
        cout << "日期4(+运算符重载):";
        d4.print();
    
        // -= 运算符重载测试
        d2 -= 3;
        cout << "日期2(-=运算符重载后):";
        d2.print();
    
        // - 运算符重载测试
        Date d5 = d3 - 7;
        cout << "日期5(-运算符重载):";
        d5.print();
    
        // - 运算符重载测试
        int diff = d5 - d4;
        cout << "日期4和日期5之间的天数差:" << diff << endl;
    
        // ++ 前置运算符重载测试
        ++d1;
        cout << "日期1(++前置运算符重载后):";
        d1.print();
    
        // ++ 后置运算符重载测试
        Date d6 = d2++;
        cout << "日期6(++后置运算符重载):";
        d6.print();
        cout << "日期2(++后置运算符重载后):";
        d2.print();
    
        // -- 前置运算符重载测试
        --d3;
        cout << "日期3(--前置运算符重载后):";
        d3.print();
    
        // -- 后置运算符重载测试
        Date d7 = d4--;
        cout << "日期7(--后置运算符重载):";
        d7.print();
        cout << "日期4(--后置运算符重载后):";
        d4.print();
    
        // 大于运算符重载测试
        cout << "日期5大于日期6吗?" << (d5 > d6 ? "是" : "否") << endl;
    
        // 等于运算符重载测试
        cout << "日期1等于日期2吗?" << (d1 == d2 ? "是" : "否") << endl;
    
        // 不等于运算符重载测试
        cout << "日期3不等于日期4吗?" << (d3 != d4 ? "是" : "否") << endl;
    
        // 输出流运算符重载测试
        cout << "日期1的输出流运算符重载:" << d1 << endl;
    
        // 输入流运算符重载测试
        Date d8;
        cout << "请输入一个日期(年 月 日):";
        cin >> d8;
        cout << "您输入的日期为:" << d8 << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    在这里插入图片描述
    C++实现一个简单的日期类,包括日期的加减、大小比较等功能。日期类的实现可以帮助我们更方便地处理日期,提高代码的可读性和可维护性。

    日期计算相关OJ题

    HJ73 计算日期到天数转换

    https://www.nowcoder.com/practice/769d45d455fe40b385ba32f97e7bcded?tpId=37&&tqId=21296&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
    在这里插入图片描述

    #include 
    using namespace std;
    
    int main() {
        int month[13] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
        int y, m, d;
        cin >> y >> m >> d;
        int day = d;
        if (2 < m && ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)))
        {
            day += 1;
        }
        day += month[m];
        cout << day << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    KY111 日期差值

    https://www.nowcoder.com/practice/ccb7383c76fc48d2bbc27a2a6319631c?tpId=62&&tqId=29468&rp=1&ru=/activity/oj&qru=/ta/sju-kaoyan/question-ranking
    在这里插入图片描述

    #include 
    #include 
    using namespace std;
    
    // 判断是否为闰年
    bool isLeapYear(int year) 
    {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    // 获取某年某月的天数
    int getDaysOfMonth(int year, int month) 
    {
        int daysOfMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && isLeapYear(year)) 
        {
            return 29;
        }
        return daysOfMonth[month];
    }
    
    // 计算日期距离公元0年的天数
    int getDaysFromZero(int year, int month, int day) 
    {
        int days = 0;
        for (int y = 1; y < year; ++y) 
        {
            days += isLeapYear(y) ? 366 : 365;
        }
        for (int m = 1; m < month; ++m) 
        {
            days += getDaysOfMonth(year, m);
        }
        days += day;
        return days;
    }
    
    // 计算两个日期之间的天数差值
    int getDaysDiff(const string& date1, const string& date2) 
    {
        int year1, month1, day1, year2, month2, day2;
        sscanf(date1.c_str(), "%4d%2d%2d", &year1, &month1, &day1);
        sscanf(date2.c_str(), "%4d%2d%2d", &year2, &month2, &day2);
    
        int days1 = getDaysFromZero(year1, month1, day1);
        int days2 = getDaysFromZero(year2, month2, day2);
    
        return abs(days2 - days1) + 1;
    }
    
    int main() 
    {
        string date1, date2;
        while (cin >> date1 >> date2) 
        {
            int daysDiff = getDaysDiff(date1, date2);
            cout << daysDiff << endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    KY222 打印日期

    https://www.nowcoder.com/practice/b1f7a77416194fd3abd63737cdfcf82b?tpId=69&&tqId=29669&rp=1&ru=/activity/oj&qru=/ta/hust-kaoyan/question-ranking
    在这里插入图片描述

    #include 
    using namespace std;
    
    bool isLeapYear(int year)
    {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    int getMonthDay(int year, int month)
    {
        int daysOfMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && isLeapYear(year)) 
        {
            return 29;
        }
        return daysOfMonth[month];
    }
    
    int main() {
        int year, day;
        while (cin >> year >> day) { 
            int month = 1;
            while (day > getMonthDay(year, month))
            {
                day -= getMonthDay(year, month);
                ++month;
            }
            printf("%4d-%02d-%02d\n",  year, month, day);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    KY258 日期累加

    https://www.nowcoder.com/practice/eebb2983b7bf40408a1360efb33f9e5d?tpId=40&&tqId=31013&rp=1&ru=/activity/oj&qru=/ta/kaoyan/question-ranking
    在这里插入图片描述

    #include 
    using namespace std;
    
    bool isLeapYear(int year)
    {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    int getMonthDay(int year, int month)
    {
        int daysOfMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && isLeapYear(year)) 
        {
            return 29;
        }
        return daysOfMonth[month];
    }
    int main() {
        int t, year, month, day, add;
        cin >> t;
        while (t--) { // 注意 while 处理多个 case
            cin >> year >> month >> day >> add;
            day += add;
            while (day > getMonthDay(year, month))
            {
                day -= getMonthDay(year, month);
                ++month;
                if (13 == month)
                {
                    month = 1;
                    ++year;
                }
            }
            printf("%4d-%02d-%02d\n",  year, month, day);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    5.中间件
    手写题目2:编写一个解析url中参数的函数
    SSM - Springboot - MyBatis-Plus 全栈体系(三十五)
    goland安装教程
    8年经验面试官详解 Java 面试秘诀
    C语言——经典200道实例(11-15)
    Spring01之ioc
    硬件开发笔记(十八):核心板与底板之间的连接方式介绍说明:板对板连接器
    人事部门OKR案例:为同事创造最佳办公环境
    富文本编辑器的实现与回显
  • 原文地址:https://blog.csdn.net/Colorful___/article/details/134387418