struct date
{
int day ; // 1 ...
int month ; // jan == 1
int year ; // 1900 ..
staticbool is_leap( int year ) ;
bool valid() const ; // return true if day, month, year constitute a valid date
date& next_day() ;
staticbool last_day_in_month( int month, int year ) ;
// ...
};
bool date::last_day_in_month( int month, int year )
{
if( month == 2 ) return is_leap(year) ? 29 : 28 ;
if( month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12 ) return 31 ;
return 30 ;
}
date& date::next_day()
{
assert( valid() ) ; // if this fails, there was a bug in our earlier code
if( day < last_day_in_month( month, year ) ) ++day ;
else // last day in month, roll over to next month
{
day = 1 ;
if( month == 12 ) { month = 1 ; ++year ; } // december, roll over to next year
else ++month ;
}
assert( valid() ) ; // if this fails, there is a bug in our next_day implementation
return *this ;
}
Consider making month an enumerated type. eg. enum month_t { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } ;
Then, we wont have to worry about the month being invalid.