Join 132,176 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,471 people online right now. Registration is fast and FREE... Join Now!
I need to find the days between two dates. I have to find the earlier of the two dates and add one day at a time, then compare the dates to find if they are equal, incrementing the diff_days variable by one for each loop until i find the dates are equal.. Thanks for your time..
cout<<"Second Date is:"<<endl; Second_Date.display_date(); cout<<endl;
if(First_Date.is_equal(Second_Date)) { cout<<"The first date you entered is the same as the second date."<<endl; days_apart = difference(First_Date,Second_Date);
}
else if(First_Date.is_less_than(Second_Date))
{ days_apart = difference(First_Date,Second_Date); cout<<"The first date you entered is earlier than the second date."<<endl;
}
else if(!(First_Date.is_less_than(Second_Date))) { days_apart = difference(Second_Date,First_Date); cout<<"The first date you entered is later than the second date"<<endl;
}
cout<<"The two days are "<< days_apart<<" days apart."<<endl;
return 0; }
int Date::exceedsDaysInMonth(){ int days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; if ( month < 1 || month > 12 || day > days[month-1]) return TRUE; else return FALSE; } // convert numeric month into string string Date::month2string(){ char *months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; if ( exceedsDaysInMonth() ) { if ( ! (month < 1 || month > 12) ) return months[month-1]; else return "Unknown month"; } else return "Unknown month"; } // return TRUE if a year is leap int Date::isLeapYear(){ if ( (year % 4) != 0 ){ return FALSE; } else if ( (year % 400) != 0 ){ return TRUE; } else if ( (year % 100) == 0 ){ return FALSE; } else { return FALSE; } } // validate and calculate next date void Date::advance(){ int td, tm, ty; int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
if ( year < 0 ){ cerr <<year << " is not a valid year" << endl; exit(1); } if ( exceedsDaysInMonth() ){ if ( month == 2 && day == 29 ){ if ( ! isLeapYear() ){ cerr << year << " is not a leap year, so Feb doesn't have 29 days" << endl; exit(1); } }
else { cerr << "Bad day value month - " << month << " (" << month2string(); cerr << ") doesn't have " << day << " days "<< endl; exit(1); } } // calculate tommorow if ( month == 2 && day == 28 && isLeapYear() == 1){ { td=day; tm=month; ty=year; td++; } }
int difference(Date date1, Date date2) {
int diff_days=0; while (!(date1.is_equal(date2))) { date1.advance(); diff_days++; } return diff_days;
}
int Date::GetMonth() {
return month; }
int Date::GetDay() { return day; }
int Date::GetYear() { return year; }
void Date::set_date(int mm, int dd, int yy) { month = mm; day = dd; year = yy;
So what's the problem you have with that code? Errors? Wrong results?
I see the advance() function doesn't really advance the date. So the while loop in difference() function is infinite.
Don't validate the date inside the advance function. Write a separate validate function for that. It's good practice.
I've written a modified advance function for you but still there are a lot of bugs in that program.
CODE
void Date::advance(){ day++; //first increment the day if(this->exceedsDaysInMonth()) //if it crosses over to the next month { day = 1; //the day becomes the first of next month month++; //increment month in that case if(month > 12) //if it crosses over to the next year { month = 1; //the month becomes the first month year++; //of the next year } } }
Also, you've made a mistake in the is_less_than(). Inside that, the second condition should have month < Second_Date.month but you've written month > Second_Date.month
Now it should work correctly. Note that exceedsDaysInMonth() doesn't check for leap year.
Hope I helped.
This post has been edited by csmanoj: 5 Oct, 2008 - 09:09 PM
cout<<"Second Date is:"<<endl; Second_Date.display_date(); cout<<endl;
if(First_Date.is_equal(Second_Date)) cout<<"The first date you entered is the same as the second date."<<endl; else if(First_Date.is_less_than(Second_Date)) cout<<"The first date you entered is earlier than the second date."<<endl; else cout<<"The first date you entered is later than the second date"<<endl;
// NEEDS work still ... crashes here ... ********************* //days_apart = First_Date.difference(Second_Date); cout<<"The two days are "<< days_apart<<" days apart."<<endl;
// return TRUE if a year is leap int Date::isLeapYear() // logic needs work .... { if ( (year % 4) != 0 ) return FALSE;
if ( (year % 400) != 0 ) return TRUE;
if ( (year % 100) == 0 ) return FALSE;
return FALSE; }
// validate and calculate next date /// needs work still ..... void Date::advance() { int td, tm, ty; int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
if ( year < 0 ) { cerr <<year << " is not a valid year" << endl; cin.sync(); cin.get(); exit(1); } if ( exceedsDaysInMonth() ) { if ( month == 2 && day == 29 ) { if ( ! isLeapYear() ) { cerr << year << " is not a leap year, so Feb doesn't have 29 days" << endl; cin.sync(); cin.get(); exit(1); } } else { cerr << "Bad day value month - " << month << " (" << month2string(); cerr << ") doesn't have " << day << " days "<< endl; cin.sync(); cin.get(); exit(1); } } // calculate tommorow if ( month == 2 && day == 28 && isLeapYear() == 1) { td=day; tm=month; ty=year; td++; } }
int Date::difference(Date &date2) { int diff_days=0; while ( !(this->is_equal(date2)) ) { this->advance(); diff_days++; } return diff_days; }
int Date::GetMonth()
{ return month; }
int Date::GetDay() { return day; }
int Date::GetYear() { return year; }
void Date::set_date(int mm, int dd, int yy) { month = mm; day = dd; year = yy; }
cout<<"Second Date is:"<<endl; Second_Date.display_date(); cout<<endl;
if(First_Date.is_equal(Second_Date)) cout<<"The first date you entered is the same as the second date."<<endl; else if(First_Date.is_less_than(Second_Date)) cout<<"The first date you entered is earlier than the second date."<<endl; else cout<<"The first date you entered is later than the second date"<<endl;
// NEEDS work still ... crashes here ... ********************* //days_apart = First_Date.difference(Second_Date); cout<<"The two days are "<< days_apart<<" days apart."<<endl;
// return TRUE if a year is leap int Date::isLeapYear() // logic needs work .... { if ( (year % 4) != 0 ) return FALSE;
if ( (year % 400) != 0 ) return TRUE;
if ( (year % 100) == 0 ) return FALSE;
return FALSE; }
// validate and calculate next date /// needs work still ..... void Date::advance() { int td, tm, ty; int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
if ( year < 0 ) { cerr <<year << " is not a valid year" << endl; cin.sync(); cin.get(); exit(1); } if ( exceedsDaysInMonth() ) { if ( month == 2 && day == 29 ) { if ( ! isLeapYear() ) { cerr << year << " is not a leap year, so Feb doesn't have 29 days" << endl; cin.sync(); cin.get(); exit(1); } } else { cerr << "Bad day value month - " << month << " (" << month2string(); cerr << ") doesn't have " << day << " days "<< endl; cin.sync(); cin.get(); exit(1); } } // calculate tommorow if ( month == 2 && day == 28 && isLeapYear() == 1) { td=day; tm=month; ty=year; td++; } }
int Date::difference(Date &date2) { int diff_days=0; while ( !(this->is_equal(date2)) ) { this->advance(); diff_days++; } return diff_days; }
int Date::GetMonth()
{ return month; }
int Date::GetDay() { return day; }
int Date::GetYear() { return year; }
void Date::set_date(int mm, int dd, int yy) { month = mm; day = dd; year = yy; }
I changed the code in the exceedDaysInMonth function to accomodate the leap year problem too.. Also, changed the other errors you pointed... Now it runs fine.. But is it the right way to check for the leap year??
int Date::exceedsDaysInMonth(){
if (isLeapYear() == 0) { int days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; if ( month < 1 || month > 12 || day > days[month-1]) return TRUE;
else
return FALSE;
} else { int days[] = {31,29,31,30,31,30,31,31,30,31,30,31}; if ( month < 1 || month > 12 || day > days[month-1]) return TRUE; else return FALSE; }}
#define TRUE 1 #define FALSE 0 using namespace std;
class Date {
private: int month; int day; int year;
public:
Date(int mm, int dd, int yy); Date( ){month=1; day=1; year=1900;}
int GetDay(); int GetMonth(); int GetYear();
int isLeapYear(); string month2string(); int exceedsDaysInMonth(); void advance();
void set_date(int mm, int dd, int yy); void display_date();
bool is_equal(Date& ); bool is_less_than(Date& );
};
int difference(Date date1, Date date2);
// Actual function Bodies
int Date::GetMonth() {
return month; }
int Date::GetDay() { return day; }
int Date::GetYear() { return year; }
void Date::set_date(int mm, int dd, int yy) { month = mm; day = dd; year = yy;
}
int Date::exceedsDaysInMonth(){
if (isLeapYear() == 0) { int days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; if ( month < 1 || month > 12 || day > days[month-1]) return TRUE;
else
return FALSE;
} else { int days[] = {31,29,31,30,31,30,31,31,30,31,30,31}; if ( month < 1 || month > 12 || day > days[month-1]) return TRUE; else return FALSE; }} // convert numeric month into string string Date::month2string(){ char *months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; if ( exceedsDaysInMonth() ) { if ( ! (month < 1 || month > 12) ) return months[month-1]; else return "Unknown month"; } else return "Unknown month"; } // return TRUE if a year is leap int Date::isLeapYear(){ if ( (year % 4) != 0 ){ return FALSE; } else if ( (year % 400) != 0 ){ return TRUE; } else if ( (year % 100) == 0 ){ return FALSE; } else { return FALSE; } }
void Date::advance(){
day++; //first increments the day
if(this->exceedsDaysInMonth()) //if it crosses over to the next month { day = 1; //the day becomes the first of next month month++; //increment month in that case if(month > 12) //if it crosses over to the next year { month = 1; //the month becomes the first month year++; //of the next year } } }
int difference(Date date1, Date date2) {
int diff_days=0; while (!(date1.is_equal(date2))){ diff_days++;
cout<<"Second Date is:"<<endl; Second_Date.display_date(); cout<<endl;
if(First_Date.is_equal(Second_Date)) { cout<<"The first date you entered is the same as the second date."<<endl; days_apart = difference(First_Date,Second_Date);
}
else if(First_Date.is_less_than(Second_Date))
{
cout<<"The first date you entered is earlier than the second date."<<endl; days_apart = difference(First_Date,Second_Date); }
cout<<"The first date you entered is later than the second date"<<endl; days_apart = difference(Second_Date,First_Date); cout<<"The two days are "<< days_apart<<" days apart."<<endl;
}
cout<<"The two dates are "<< days_apart<<" days apart."<<endl;
I saw you defined const bool FALSE =false; const bool TRUE = true;
i got errors when i used this statement. I removed it and it worked.. Why is this needed? By default, bool returns '1' if True and '0' if False??
It it not needed ... I just left in what you had done ... but changed the #define FALSE 0 to const bool FALSE =false;
etc. ...
which compiled ok at this end
But I did wonder why you were using TRUE and FALSE when true and false are defined in C++ ?
Now ... here is something for you to consider ...
CODE
/* Could still use some more polish ... like crash proofing on bad input and validating the dates input, that they are real dates? (Also see in line comments... ) but it now .... seems ...to give the right answers ... for leap years too ... :) */
#include<iostream> //#include<fstream> // These are not used here ... // //#include<cstdlib> //#include<cctype> //#include<cmath> #include<string> //#include<cstring> //#include<iomanip>
#define debugging true // to switch in a working 'isLeapYear()'
using namespace std;
class Date {
private: int month; int day; int year;
public:
Date(int mm, int dd, int yy); Date() { month=1; day=1; year=1900; }
int GetDay(); int GetMonth(); int GetYear();
// some of these can be private, the ones NOT called 'outside' ... //*** bool isLeapYear(); string month2string(); //*** bool exceedsDaysInMonth();//*** void advance(); // could be private if 'difference' was part of class //***
void set_date(int mm, int dd, int yy); void display_date();
// helper function .... int difference( Date &date1, Date &date2 ) // Why not part of class? { int diff_days = 0; while ( !date1.is_equal(date2) ) { diff_days++; date1.advance(); } return diff_days; }
// Actual function Bodies
int Date::GetMonth() { return month; }
int Date::GetDay() { return day; }
int Date::GetYear() { return year; }
void Date::set_date(int mm, int dd, int yy) { month = mm; day = dd; year = yy; }
bool Date::exceedsDaysInMonth() { // moved here so not repeated in 'else' ... int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
if( !isLeapYear() ) { if ( month > 12 || day > days[month]) return true;
return false; } else // is leap year ... so need to handle case of month == Feb { if ( month == 2 && day == 29 ) //<-- the 'tricky' condition to get right return false; if ( month > 12 || day > days[month] ) return true;
return false; } }
// convert numeric month into string string Date::month2string() { char *months[] = {"***", "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; if ( !exceedsDaysInMonth() ) // 'exceedsDaysInMonth()' can be 'private' ... { if ( month >= 1 && month <= 12 ) return months[month]; else return "Unknown month"; } else return "Unknown month"; }
#if debugging // BELOW is a working example ... bool Date::isLeapYear() { if (year%4 != 0) return false; // not a leap year if (year%100 == 0 && year%400 != 0) return false; // not a leap year return true; }
#else // return true if a year is leapyear bool Date::isLeapYear() { if ( year%4 != 0 ) return false; // it EXITS here 'false' if ( year % 400 != 0 ) return true; // or .... HERE ... 'true'
// once you get to here ... both of your returns are 'false' // so onlu one EXIT woyuld be needed ... BUT IS your logic ok? See above ex. /* if ( year % 100 == 0 ) return false; */
return false; /// or HERE ... 'false' } #endif
void Date::advance() { day++; //first increment the day if( this->exceedsDaysInMonth() )//if it crosses over to the next month { day = 1; //the day becomes the first of next month month++; //increment month in that case if(month > 12) //if it crosses over to the next year { month = 1; //the month becomes the first month year++; //of the next year } } }
bool Date::is_equal( Date& Second_Date ) { if ( month==Second_Date.month && day==Second_Date.day && year==Second_Date.year ) return true; // if reach here ... return false; }
bool Date::is_less_than( Date& Second_Date ) { if( year < Second_Date.year) return true; if( year <= Second_Date.year && month < Second_Date.month ) return true; if( year <= Second_Date.year && month <= Second_Date.month && day < Second_Date.day ) return true; // if reach here ... return false; }
// ------------------ Main Program---------------------------------
int main() { // DON'T NEED all these ... can use some over again //int m1, m2, d1, d2, y1, y2, index=0, diff_days= 0; //int mm1, mm2, dd1, dd2, yy1, yy2, days_apart;
int m, d, y; // These are all that you need ... int mm, dd, yy, days_apart; char slash; Date First_Date, Second_Date;
cout<<"This program gives the number of days between two dates."<<endl;
TESTING: cout<<"Please enter a date in the form mm/dd/yyyy : ";
cin>>m>>slash>>d>>slash>>y;
First_Date.set_date(m, d, y); // need to validate that this is a possible date
cout<<"First Date is:"<<endl; First_Date.display_date(); cout<<endl;
cout<<"Please enter a second date in the form mm/dd/yyyy : ";
cin>>m>>slash>>d>>slash>>y; Second_Date.set_date(m, d, y); // need to validate ...
cout<<"Second Date is:"<<endl; Second_Date.display_date(); cout<<endl;
if(First_Date.is_equal(Second_Date)) { cout<<"The first date you entered is the same as the second date."<<endl; days_apart = difference(First_Date,Second_Date); } else if(First_Date.is_less_than(Second_Date)) { cout<<"The first date you entered is earlier than the second date."<<endl; days_apart = difference(First_Date,Second_Date); }
else // the date can only be equal or less than ...or ELSE it is greater { cout<<"The first date you entered is later than the second date"<<endl; days_apart = difference(Second_Date,First_Date); // cout<<"The two days are "<< days_apart<<" days apart."<<endl; }
cout<<"The two dates are "<< days_apart<<" days apart.\n" <<".. or have " << days_apart+1 << " inclusive days between them.\n\n" << flush;
cin.clear(); cin.sync(); goto TESTING;
cin.get(); return 0; }
/* Quick question, is the year 2000 a leap year? A suprising number of people give the wrong answer. The correct answer is "yes", that is 2000 is a leap year. Why do so many folks give the wrong answer to this simple question? In general, a year is a leap year if it is evenly divisible by 4. Most people also remember the exception which is a year is not a leap year if it ends in "00" (ie., the year is even divisable by 100). So years like 1972, 1980, and 1996 are leap years, but 1800 and 1900 are not.
So why then is a 2000 a leap year? What many folks do not realize is that the 100 year exception itself has an exception. Years that are evenly divisable by 400 are leap years. So 2000 as well as 2400 will be leap years.
Programmers who write date conversion code and don't know about the "exception to the exception" will end up creating software which will display incorrect dates starting Feb. 29th, 2000. The incorrect conversions software will instead give Feb. 29th as March 1. Even worse, all subsequent dates will likely be off by one day also.
Although the Leap Year 2000 bug is not technically the same as the Y2K bug, it is many times lumped together Y2K bug because it occurs so close to Jan. 1, 2000.
Over the years, operating systems and development tools have shipped with the "Leap Year 2000" bug in them. This means that applications that use these broken operating systems or tools will also have the bug. However, over the last 5 years with the all of the talk of the Y2K bug, most of the problems have been fixed.
*/
This post has been edited by David W: 9 Oct, 2008 - 07:01 AM