You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Date类计算日期天数差问题:首日期大于次日期时无法计算

问题分析

你的days_between函数存在两个核心问题:

  • 仅支持起始日期早于等于结束日期的场景,当起始日期更晚时,inc_one_day会不断让日期往后走,永远追不上更早的目标日期,导致无限循环。
  • 初始计数count = 1是错误的:如果两个日期相同,应该返回0天差,而不是1。
解决方案

我们需要给Date类添加减少一天的方法,然后在计算天数差时先判断日期的先后关系,选择递增或递减日期来计数,同时修正计数初始值。

1. 添加dec_one_day方法

在Date类的public声明中添加:

void dec_one_day();

然后实现该方法:

void Date::dec_one_day(){
    day--;
    if (day < 1) {
        month--;
        if (month < 1) {
            month = 12;
            year--;
        }
        day = days_of_month(month, year);
    }
}

这个方法的逻辑和inc_one_day相反:先减日期,若日期小于1,则回退到上月的最后一天;若月份小于1,则回退到上一年的12月。

2. 修改days_between函数

新增辅助函数判断日期先后,再根据情况选择递增或递减的方式计数,同时修正初始值:

// 辅助函数:判断d1是否早于d2
bool is_before(Date d1, Date d2) {
    if (d1.get_year() != d2.get_year())
        return d1.get_year() < d2.get_year();
    if (d1.get_month() != d2.get_month())
        return d1.get_month() < d2.get_month();
    return d1.get_day() < d2.get_day();
}

int days_between(Date d1, Date d2){
    int count = 0;
    if (is_before(d1, d2)) {
        // d1更早,递增d1直到等于d2
        while (!d1.equals(d2)){
            d1.inc_one_day();
            count++;
        }
    } else {
        // d1更晚,递减d1直到等于d2
        while (!d1.equals(d2)){
            d1.dec_one_day();
            count++;
        }
    }
    return count;
}

3. 完整修改后的代码

#include <iostream>
#include <cstdlib>
using namespace std;

class Date {
public:
    Date(int d, int m, int y);
    void set_date(int d, int m, int y);
    void print_date();
    void inc_one_day();
    void dec_one_day(); // 新增的方法
    bool equals(Date d);
    int get_day() { return day; }
    int get_month() { return month; }
    int get_year() { return year; }
private:
    int day;
    int month;
    int year;
};

bool is_leap_year(int year)
{
    int r = year % 33;
    return r == 1 || r == 5 || r == 9 || r == 13 || r == 17 || r == 22 || r == 26 || r == 30;
}

int days_of_month(int m, int y){
    if (m < 7)
        return 31;
    else if (m < 12)
        return 30;
    else if (m == 12)
        return is_leap_year(y) ? 30 : 29;
    else
        abort();
}

void Date::inc_one_day(){
    day++;
    if (day > days_of_month(month, year)) {
        day = 1;
        month++;
        if (month > 12) {
            month = 1;
            year++;
        }
    }
}

// 实现dec_one_day方法
void Date::dec_one_day(){
    day--;
    if (day < 1) {
        month--;
        if (month < 1) {
            month = 12;
            year--;
        }
        day = days_of_month(month, year);
    }
}

bool Date::equals(Date d) {
    return day == d.day && month == d.month && year == d.year;
}

// 辅助函数:判断d1是否早于d2
bool is_before(Date d1, Date d2) {
    if (d1.get_year() != d2.get_year())
        return d1.get_year() < d2.get_year();
    if (d1.get_month() != d2.get_month())
        return d1.get_month() < d2.get_month();
    return d1.get_day() < d2.get_day();
}

int days_between(Date d1, Date d2){
    int count = 0;
    if (is_before(d1, d2)) {
        while (!d1.equals(d2)){
            d1.inc_one_day();
            count++;
        }
    } else {
        while (!d1.equals(d2)){
            d1.dec_one_day();
            count++;
        }
    }
    return count;
}

Date::Date(int d, int m, int y){
    cout << "constructor called \n";
    set_date(d, m, y);
}

void Date::set_date(int d, int m, int y){
    if (y < 0 || m < 1 || m>12 || d < 1 || d > days_of_month(m, y))
        abort();
    day = d;
    month = m;
    year = y;
}

void Date::print_date(){
    cout << day << '/' << month << '/' << year << endl;
}

int main(){
    Date bd(22, 12, 1395);
    Date be(15, 12, 1395);
    cout << '\n';
    int i = days_between(bd, be);
    cout << i << endl; // 现在会输出7,符合预期
}
测试验证

运行修改后的代码,输入22/12/1395和15/12/1395,程序会输出7;如果输入两个相同日期,会输出0,均符合预期。

内容的提问来源于stack exchange,提问作者lila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:05:32