//Data.h
#include <iostream>
#include <string>
using namespace std;
class Date
{
public:
enum Month { jan = 1, feb, mar, apr, may, jun,
jul, aug, sep, oct, nov, dec };
class BadDate{ };
Date(int dd = 0, Month mm = Month(0), int yy = 0);
int day( ) const;
Month month( ) const;
int year( ) const;
//string string_rep( ) const;
//void char_rep(char s[]) const;
void print_date( );
//使用Date之前应调用set_default函数设置缺省日期
static void set_default(int, Month, int);
Date& add_year(int n);
Date& add_month(int n);
Date& add_day(int n);
private:
int d;
Month m;
int y;
static Date default_date;
int get_days(Month mm);
};
int leapyear(int yy);
//Date.cpp
#include "Date.h"
Date::Date(int dd, Month mm, int yy)
{
if(yy == 0)
y = default_date.year( );
if(mm == Month(0))
m = default_date.month( );
if(dd == 0)
d = default_date.day( );
int max;
switch(mm)
{
case feb:
max = 28 + leapyear(yy);
break;
case apr:
case jun:
case sep:
case nov:
max = 30;
break;
case jan:
case mar:
case may:
case jul:
case aug:
case oct:
case dec:
max = 31;
break;
default:
throw BadDate( );
}
if(dd < 1 || dd > max)
throw BadDate( );
y = yy;
m = mm;
d = dd;
}
int Date::day( ) const
{
return d;
}
enum Date::Month Date::month( ) const
{
return m;
}
int Date::year( ) const
{
return y;
}
void Date::set_default(int d, Month m, int y)
{
default_date = Date(d, m, y);
}
Date& Date::add_year(int n)
{
if(n != 0)
{
if( d == 29 && m == feb && !leapyear(y + n) )
{
d = 28;
}
y = y + n;
}
return *this;
}
Date& Date::add_month(int n)
{
if(n == 0)
return *this;
if(n > 0)
{
int delta_y = n/12;
int mm = m + n%12;
if(mm > 12)
{
delta_y++;
mm -= 12;
}
y += delta_y;
if(mm == 2 && d >28)
{
if( leapyear(y) )
d = 29;
else
d = 28;
}
if(d == 31)
{
if( (mm == apr) || (mm == jun) ||
(mm == sep) || (mm == nov) )
{
d = 30;
}
}
m = Month(mm);
return *this;
}
if(n < 0)
{
n = -n;
int delta_y = n/12;
int mm = m - n%12;
if(mm <= 0)
{
delta_y++;
mm += 12;
}
y -= delta_y;
if(mm == 2 && d >28)
{
if( leapyear(y) )
d = 29;
else
d = 28;
}
if(d == 31)
{
if( (mm == apr) || (mm == jun) ||
(mm == sep) || (mm == nov) )
{
d = 30;
}
}
m = Month(mm);
return *this;
}
return *this;
}
Date& Date::add_day(int n)
{
if( n == 0 )
return *this;
if( n > 0 )
{
//计算本月剩余天数
int totalDays = get_days(m);
int daysLeft = totalDays - d;
if(n <= daysLeft)
{
d = d + n;
}
else if(n > daysLeft)
{
//把日期调整到下个月1号
n = n - (daysLeft + 1);
add_month(1);
d = 1;
//模拟时间按月的流逝,最后得到正确的日期
int daysInMonth = get_days(m);
while( n >= daysInMonth )
{
add_month(1);
n = n - daysInMonth;
daysInMonth = get_days(m);
}
d = d + n;
}
}
else if( n < 0 )
{
//把n变为正值
n = -n;
//计算本月剩余天数
int totalDays = get_days(m);
int daysLeft = totalDays - d;
//把时间调整到本月的最后一天
n = n + daysLeft;
d = d + daysLeft;
//模拟时间按月的倒流,最后得到正确的日期
int daysInMonth = get_days(m);
while( n >= daysInMonth )
{
add_month(-1);
n = n - daysInMonth;
daysInMonth = get_days(m);
}
d = d - n;
}
return *this;
}
int Date::get_days(Month mm)
{
int days;
if(mm == 0)
return 0;
switch(mm)
{
case jan:
case mar:
case may:
case jul:
case aug:
case oct:
case dec:
days = 31;
break;
case apr:
case jun:
case sep:
case nov:
days = 30;
break;
case feb:
days = 28 + leapyear(y);
}
return days;
}
void Date::print_date( )
{
cout<<y<<'-'<<m<<'-'<<d<<endl;
}
int leapyear(int yy)
{
int iRet = 0;
if( (yy % 4 == 0) && (yy % 100 != 0) )
iRet = 1;
if( yy % 400 == 0 )
iRet = 1;
return iRet;
}
Date Date::default_date(3, feb, 1981);
int main( )
{
//Date::set_default();
Date testDate(29, Date::Month::feb, 2000);
testDate.print_date( );
cout<<"after add -1 years:";
testDate.add_year(-1);
testDate.print_date( );
system("pause");
return 0;
}