1 ///////////////////////////////////////////////////////////
2 // Softwarebauelemente II, Aufgabe O2.1
3 //
4 // author: Stephan Brumme
5 // last changes: February 26, 2001
6
7
8 #include "Date.h"
9 #include <iostream>
10
11 // we are using OS-specific date/time operations
12 #include <time.h>
13
14
15
16
17 // constructor, default value is 0/0/00 (invalid date !)
18 CDate::CDate(int nDay, int nMonth, int nYear)
19 {
20 // store date
21 m_nDay = nDay;
22 m_nMonth = nMonth;
23 m_nYear = nYear;
24 }
25
26
27 // attention ! this method is NOT part of CDate
28 ostream& operator<<(ostream &mystream, const CDate& date)
29 {
30 return date.OutStream(mystream);
31 }
32
33
34 // used to perform proper display in derived classes
35 ostream& CDate::OutStream(ostream& mystream, bool bDebug) const
36 {
37 if (!bDebug)
38 {
39 mystream << m_nDay << "." << m_nMonth << "." << m_nYear;
40 }
41 else
42 {
43 mystream << "DEBUG info for '" << ClassnameOf() << "'" << endl
44 << " m_nDay=" << m_nDay
45 << " m_nMonth=" << m_nMonth
46 << " m_nYear=" << m_nYear;
47 }
48
49 return mystream;
50 }
51
52
53 // return current date
54 CDate CDate::GetToday()
55 {
56 CDate dtReturn;
57
58 // the following code is taken from MSDN
59
60 // use system functions to get the current date as UTC
61 time_t secondsSince1970;
62 time(&secondsSince1970);
63
64 // convert UTC to local time zone
65 struct tm *localTime;
66 localTime = localtime(&secondsSince1970);
67
68 // store retrieved date
69 dtReturn.m_nDay = localTime->tm_mday;
70 dtReturn.m_nMonth = localTime->tm_mon + 1;
71 dtReturn.m_nYear = localTime->tm_year + 1900;
72
73 return dtReturn;
74 }
75
76
77 // validate a date
78 bool CDate::IsValid() const
79 {
80 // validate month
81 if (m_nMonth < JANUARY || m_nMonth > DECEMBER)
82 return false;
83
84 // days per month, february ma(r)y vary !!!
85 int nDaysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
86
87 // adjust days of february
88 if (IsLeapYear(m_nYear))
89 nDaysPerMonth[FEBRUARY]++;
90
91 // validate day
92 if (m_nDay < 1 || m_nDay > nDaysPerMonth[m_nMonth])
93 return false;
94
95 // day and month are valid
96 return true;
97 }
98
99
100 // determine whether it is a leap year
101 bool CDate::IsLeapYear(int nYear)
102 {
103 // used to speed up code, may be deleted
104 if (nYear % 4 != 0)
105 return false;
106
107 // algorithm taken from MSDN, just converted from VBA to C++
108 if (nYear % 400 == 0)
109 return true;
110 if (nYear % 100 == 0)
111 return false;
112 if (nYear % 4 == 0)
113 return true;
114
115 // this line won't be executed because of optimization (see above)
116 return false;
117 }
118
119
120 // copy constructor
121 CDate& CDate::operator =(const CDate &date)
122 {
123 m_nDay = date.m_nDay;
124 m_nMonth = date.m_nMonth;
125 m_nYear = date.m_nYear;
126 // m_bDebug is not copied !
127
128 return *this;
129 }
130
131
132 // virtual, see operator=
133 bool CDate::Copy(const CDate *date)
134 {
135 // invalid class
136 if (date == NULL || date == this)
137 return false;
138
139 // use non virtual reference based copy
140 // return value isn't needed
141 operator=(*date);
142
143 // we're done
144 return true;
145 }
146
147
148 // compare two dates
149 bool CDate::operator ==(const CDate &date) const
150 {
151 // m_bDebug is not neccessary
152 return (m_nDay == date.m_nDay &&
153 m_nMonth == date.m_nMonth &&
154 m_nYear == date.m_nYear);
155 }
156
157
158 // virtual, see operator==
159 bool CDate::EqualValue(CDate *date) const
160 {
161 // invalid class
162 if (date == NULL)
163 return false;
164
165 // use non virtual reference based copy
166 return operator==(*date);
167 }
168
169
170 // set attributes, returns validility of date
171 inline bool CDate::SetDay(int nDay)
172 {
173 m_nDay = nDay;
174 return IsValid();
175 }
176 inline bool CDate::SetMonth(int nMonth)
177 {
178 m_nMonth = nMonth;
179 return IsValid();
180 }
181 inline bool CDate::SetYear(int nYear)
182 {
183 m_nYear = nYear;
184 return IsValid();
185 }
186
187 // return attributes
188 inline int CDate::GetDay() const
189 {
190 return m_nDay;
191 }
192 inline int CDate::GetMonth() const
193 {
194 return m_nMonth;
195 }
196 inline int CDate::GetYear() const
197 {
198 return m_nYear;
199 }
200