First things first. Learn to design a decent class first. The math behind all this is hard enough. So let's setup a decent class and then see if you can manage it from here. If not, then feel free to come back.
Date.h Code:
#ifndef DATE_H
#define DATE_H
#include <ctime>
class Date
{
public:
enum month
{jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum week_day
{ mon = 1, tue, wed, thu, fri, sat, sun };
static const int REFORM_YEAR;
static const month REFORM_MONTH;
static const unsigned REFORM_DAY_NUMBER;
public: //Ctors et al. only.
Date();
Date(month, int, int);
public: //Accessors only. int get_year() const;
int get_day() const;
month get_month() const;
public:
static int days_in_month(month, int);
static bool is_leap(int);
protected:
void set_date(month, int, int);
unsigned long calc_day_number() const;
private:
month month_;
int day_;
int year_;
unsigned long daynumber_;
};
/***************** inlines ***************/ inline int Date::get_year() const
{
return year_;
}
//----------------------------------------- inline int Date::get_day() const
{
return day_;
}
//----------------------------------------- inline Date::month Date::get_month() const
{
return month_;
}
//----------------------------------------- #endif //DATE_H Date.cpp Code:
#include "Date.h" const int Date::REFORM_YEAR = 1582;
const unsigned Date::REFORM_DAY_NUMBER = 577737L;
const Date::month Date::REFORM_MONTH = Date::oct;
//-----------------------------------------------------
Date::Date()
{
set_date(jan, 1, 1);
}
//-----------------------------------------------------
Date::Date(month m, int d, int y)
{
set_date(m, d, y);
}
//----------------------------------------------------- void Date::set_date(month m, int d, int y)
{
month_ = m;
day_ = d;
year_ = y;
daynumber_ = calc_day_number();
}
//---------------------------------------------------- bool Date::is_leap(int yr)
{
if( yr % 4 ) return false;
if( yr < REFORM_YEAR ) return true;
if( yr % 100 ) return true;
if( yr % 400 ) return false;
return true;
}
//----------------------------------------------------- int Date::days_in_month(month mth, int yr)
{
static const int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
if( yr == REFORM_YEAR && mth == REFORM_MONTH )
{
return 21;
}
return days[mth] + (feb == mth && is_leap(yr));
}
//----------------------------------------------------- unsigned long Date::calc_day_number() const
{
long days;
long year = (long)year_ - 1L;
days = year * 365L + year / 4L - year / 100L + year / 400L;
//Years before 1582 were all leap if it is divisible by 4. if( year > REFORM_YEAR )
{
days += 12;
}
else
{
days += year / 100L;
days -= year / 400L;
}
for( int i = jan; i < month_; ++i )
{
days += days_in_month((month)i, year_);
}
days += day_;
//Adjust for the 10 missing days (Oct 4 - Oct 15, 1582). if( days > REFORM_DAY_NUMBER )
{
days -= 10L;
}
return days;
} main.cpp Code:
#include "Date.h" #include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Date dt;
cout << dt.get_day() << " " << dt.get_month() << " " << dt.get_year() << endl;
cin.get();
return 0;
} The
calc_day_number() method is your key to success if you want to implement the
next_day() function.
Here are the global steps:
1) Implement an overloaded
operator+().
2) Implement a method that calculates the total amount of days added with the number of days you want. Make it calculate the year, month and day.
For example if day_number is day_number+1, then check if the resulting day_number > refordaynumber. If it is, then add 10 days to the resulting day_number! That is because there are 10 days missing because pope Gregor XXLLLCXXX (or something) reformed it.
3) The year_ is then obviously: (int)daynumber_ / 365. Duh.
4) The day_ is INITIALLY: (int)daynumber_ % 365L. Convince your self!
5) Adjust the initial day IF resulting years_ < 1700.
6) And/Or adjust the initial day_, taking leap years into account.
Etcetera etcetera. I needed to study for this too. And now I want a break. See how far you can get. Be welcome anytime. But beware, I do not like lazy folks.