// date8.cpp

#include <iostream.h>
#include <time.h>
#include <assert.h>
#include "date8.h"

// Must initialize statics outside the class definition
int Date::dtab[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}
};

Date Date::operator-(const Date& d2) const
{
    int months, days, years, prev_month, order;
    const Date * first, * last;
    
    // Must know which date is first
    if (compare(d2) <= 0)
    {
        // this <= d2
        order = -1;
        first = this;
        last = &d2;
    }
    else
    {
        order = 1;
        first = &d2;
        last = this;
    }
    
    // Compute the interval; first <= last
    years = last->year - first->year;
    months = last->month - first->month;
    days = last->day - first->day;
    assert(years >= 0 && months >= 0 && days >= 0);

    // Do obvious corrections (days before months!)
    //
    // This is a loop in case the previous month is
    // February, and days < -28.
    prev_month = last->month - 1;
    while (days < 0)
    {
        // Borrow from the previous month
        if (prev_month == 0)
            prev_month = 12;
        --months;
        days += dtab[isleap(last->year)][prev_month--];
    }

    if (months < 0)
    {
        // Borrow from the previous year
        --years;
        months += 12;
    }

    // Return a date object with the interval
    if (order == -1)
        return Date(-months,-days,-years);
    else
        return Date(months,days,years);
}

int Date::compare(const Date& d2) const
{
    int months, days, years, order;
    
    years = year - d2.year;
    months = month - d2.month;
    days = day - d2.day;

    // return <0, 0, or >0, like strcmp()
    if (years == 0 && months == 0 && days == 0)
        return 0;
    else if (years == 0 && months == 0)
        return days;
    else if (years == 0)
        return months;
    else
        return years;
}

ostream& operator<<(ostream& os, const Date& d)
{
    os << d.month << '/' << d.day << '/' << d.year;
    return os;
}

istream& operator>>(istream& is, Date& d)
{
    char slash;
    is >> d.month >> slash >> d.day >> slash >> d.year;
    return is;
}

Date::Date()
{
    // Get today's date
    time_t tval = time(0);
    struct tm *tmp = localtime(&tval);

    month = tmp->tm_mon+1;
    day = tmp->tm_mday;
    year = tmp->tm_year + 1900;
}


