#include
using std::cout;
using std::endl;
using std::ostream;
class date {
public:
date(int y, int m, int d) : year(y), month(m), day(d)
{ check(); }
int get_year() const { return year; }
void set_year(int y) { year = y; check(); }
int get_month() const { return month; }
void set_month(int m) { month = m; check(); }
int get_day() const { return day; }
void set_day(int d) { day = d; check(); }
int days_between (const date &d) const {
return this->before(d) ? days_between_impl(d)
: d.days_between(*this);
}
private:
int year, month, day;
void check() {
if (month < 1 || month > 12) month = 1;
if (day < 1 || day > days_of_month[is_leap_year(year)][month])
day = 1;
}
bool before(const date &d) const {
if (this->year != d.year)
return this->year < d.year;
if (this->month != d.month)
return this->month < d.month;
return this->day < d.day;
}
int days_between_impl (const date &d) const {
if (this->year == d.year) {
return this->days_remain_this_year() - d.days_remain_this_year();
}
return this->days_remain_this_year() + d.days_passed_this_year()
+ days_between_years(this->year + 1, d.year);
}
int days_remain_this_year() const {
int days = days_of_month[is_leap_year(year)][month] - day;
for (int m = month + 1; m <= 12; ++m)
days += days_of_month[is_leap_year(year)][m];
return days;
}
int days_passed_this_year() const {
int days = day;
for (int m = 1; m < month; ++m)
days += days_of_month[is_leap_year(year)][m];
return days;
}
static int days_between_years(int y1, int y2) {
int days = 0;
for ( ; y1 < y2; ++y1) {
days += (is_leap_year(y1) == 1 ? 366 : 365);
}
return days;
}
static int is_leap_year(int y) {
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0) ? 1 : 0;
}
static int days_of_month[2][13];
};
int date::days_of_month[2][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, },
};
ostream & operator<< (ostream &out, const date &d) {
out << d.get_year() << "/" << d.get_month() << "/" << d.get_day();
return out;
}
int main() {
date d1(2008, 1, 1);
date d2(2008, 5, 1);
cout << d1.days_between(d2) << " days between " << d1 << " and " << d2 << endl;
return 0;
}