#
include
"Date.h"
#
include
<iostream>
#
include
<sstream>
#
include
<cstdlib>
#
include
<string>
#
include
<algorithm>
//
For
swap()
#
include
<ctime>
#
include
<cassert>
#
include
<iomanip>
using
namespace
std;
namespace
{
const
int
daysInMonth[][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
}
}
;
inline
bool
isleap
(int
y) {
return
y%
4
=
=
0
&
&
y%
100
!
=
0
|
|
y%
400
=
=
0
;
}
}
Date::
Date
() {
time_t tval =
time
(0
);
struct
tm *
now =
localtime
(&
tval);
year =
now-
>
tm_year +
1900
;
month =
now-
>
tm_mon +
1
;
day =
now-
>
tm_mday;
}
Date::
Date
(int
yr,int
mon,int
dy)
throw
(Date::
DateError) {
if
(!
(1
<=
mon &
&
mon <=
12
))
throw
DateError
("
Bad
month
in
Date
ctor"
);
if
(!
(1
<=
dy &
&
dy <=
daysInMonth[isleap
(year)][mon]))
throw
DateError
("
Bad
day
in
Date
ctor
"
);
year =
yr;
month =
mon;
day =
dy;
}
Date::
Date
(const
std::
string&
s)
throw
(Date::
DateError) {
if
(!
(s.size
() =
=
8
))
throw
DateError
("
Bad
string
in
Date
ctor"
);
for
(int
n =
8
; -
-
n >=
0
;)
if
(!
isdigit
(s[n]))
throw
DateError
("
Bad
string
in
Date
ctor"
);
string buf =
s.substr
(0
, 4
);
year =
atoi
(buf.c_str
());
buf =
s.substr
(4
, 2
);
month =
atoi
(buf.c_str
());
buf =
s.substr
(6
, 2
);
day =
atoi
(buf.c_str
());
if
(!
(1
<=
month &
&
month <=
12
))
throw
DateError
("
Bad
month
in
Date
ctor"
);
if
(!
(1
<=
day &
&
day
<=
daysInMonth[isleap
(year)][month]))
throw
DateError
("
Bad
day
in
Date
ctor
"
);
}
int
Date::
getYear
() const
{
return
year; }
int
Date::
getMonth
() const
{
return
month; }
int
Date::
getDay
() const
{
return
day; }
string Date::
toString
() const
{
ostringstream os;
os.fill
('
0
'
);
os <
<
setw
(4
) <
<
year
<
<
setw
(2
) <
<
month
<
<
setw
(2
) <
<
day;
return
os.str
();
}
int
Date::
compare
(const
Date&
d2) const
{
int
result =
year -
d2.year;
if
(result =
=
0
) {
result =
month -
d2.month;
if
(result =
=
0
)
result =
day -
d2.day;
}
return
result;
}
int
Date::
daysInPrevMonth
(int
year, int
month) {
if
(month =
=
1
) {
-
-
year;
month =
12
;
}
else
-
-
month;
return
daysInMonth[isleap
(year)][month];
}
bool
operator
<
(const
Date&
d1, const
Date&
d2) {
return
d1.compare
(d2) <
0
;
}
bool
operator
<=
(const
Date&
d1, const
Date&
d2) {
return
d1 <
d2 |
|
d1 =
=
d2;
}
bool
operator
>
(const
Date&
d1, const
Date&
d2) {
return
!
(d1 <
d2) &
&
!
(d1 =
=
d2);
}
bool
operator
>=
(const
Date&
d1, const
Date&
d2) {
return
!
(d1 <
d2);
}
bool
operator
=
=
(const
Date&
d1, const
Date&
d2)
{
return
d1.compare
(d2) =
=
0
;
}
bool
operator
!
=
(const
Date&
d1, const
Date&
d2)
{
return
!
(d1 =
=
d2);
}
Date::
Duration
duration
(const
Date&
date1, const
Date&
date2)
{
int
y1 =
date1.year;
int
y2 =
date2.year;
int
m1 =
date1.month;
int
m2 =
date2.month;
int
d1 =
date1.day;
int
d2 =
date2.day;
int
order =
date1.compare
(date2);
if
(order =
=
0
)
return
Date::
Duration
(0
,0
,0
);
else
if
(order >
0
) {
using
std::
swap;
swap
(y1, y2);
swap
(m1, m2);
swap
(d1, d2);
}
int
years =
y2 -
y1;
int
months =
m2 -
m1;
int
days =
d2 -
d1;
assert
(years >
0
|
|
years =
=
0
&
&
months >
0
|
|
years =
=
0
&
&
months =
=
0
&
&
days
>
0
);
int
lastMonth =
m2;
int
lastYear =
y2;
while
(days <
0
) {
assert
(months >
0
);
days +
=
Date::
daysInPrevMonth
(
lastYear, lastMonth-
-
);
-
-
months;
}
if
(months <
0
) {
assert
(years >
0
);
months +
=
12
;
-
-
years;
}
return
Date::
Duration
(years, months, days);
}
ostream&
operator
<
<
(ostream&
os, const
Date&
d) {
char
fillc =
os.fill
('
0
'
);
os <
<
setw
(2
) <
<
d.getMonth
() <
<
‘-
‘
<
<
setw
(2
) <
<
d.getDay
() <
<
‘-
‘
<
<
setw
(4
) <
<
setfill
(fillc) <
<
d.getYear
();
return
os;
}
istream&
operator
>
>
(istream&
is,
Date&
d) {
is >
>
d.month;
char
dash;
is >
>
dash;
if
(dash !
=
'
-
'
)
is.setstate
(ios::
failbit);
is >
>
d.day;
is >
>
dash;
if
(dash !
=
'
-
'
)
is.setstate
(ios::
failbit);
is >
>
d.year;
return
is;
}