when the first date is bigger than the second, it doesent calculate. for example: first date 22/10/2022 second date: 15/10/2022
#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();
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 ;
}
}
}
bool Date::equals(Date d) {
return day == d.day && month == d.month && year == d.year;
}
int days_between(Date d1, Date d2){
int count = 1;
while (!d1.equals(d2)){
d1.inc_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;
i= days_between(bd, be);
cout << i << endl;
}
here's my code. I've seen many codes that calculate the days between two dates, but they didn't use class Date. how can i solve this problem? could you guys help me please.I'm sorry i'm new in c so, my problem might be so basic.
CodePudding user response:
What would be easier is to write a function that calculates the total number of days that have occurred since the year 0000. After that you can simply subtract them from each other and return the total number of days between them.
CodePudding user response:
It is clear why your algorithm does not work - you are incrementing the later date so it will never equal the earlier date. The solution is simply to compare the dates and swap the operands if necessary so that you are always incrementing the earlier date toward the later date.
int days_between(Date d1, Date d2)
{
int count = 0 ;
// Initially assume d2 >= d1
Date* earlier = &d1 ;
Date* later = &d2 ;
// Test if d1 > d2...
int year_diff = d2.get_year() - d1.get_year() ;
int mon_diff = d2.get_month() - d1.get_month() ;
int day_diff = d2.get_day() - d1.get_day() ;
if( year_diff < 0 ||
(year_diff == 0 && (mon_diff < 0 || (mon_diff == 0 &&
day_diff < 0 ))))
{
// d1 > d2, so swap
earlier = &d2 ;
later = &d1 ;
}
while (!earlier->equals(*later))
{
earlier->inc_one_day();
count ;
}
return count;
}
Note that it is not clear why you start with a count of 1. If the dates start equal, surely that should return a zero? That is how I have written it in any case.
If it is required to indicate whether the dates were reversed or not, you might want to return a signed value. In that case:
return earlier == &d2 ? -count : count ;
Which for the dates in your example will return -7.
Your solution is a good candidate for operator overloading so you could simply and more intuitively write:
if( d1 > d2 )
{
earlier = &d2 ;
later = &d1 ;
}
while( *earlier != *later))
{
earlier ;
count ;
}
return earlier == &d2 ? -count : count ;
and even ultimately:
i = be - bd;