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
相关产品推荐
相关产品推荐

