/////////////////////////////////////////////////////////// // Softwarebauelemente II, Aufgabe O2.1 // // author: Stephan Brumme // last changes: February 26, 2001 #include "Date.h" #include // we are using OS-specific date/time operations #include // constructor, default value is 0/0/00 (invalid date !) CDate::CDate(int nDay, int nMonth, int nYear) { // store date m_nDay = nDay; m_nMonth = nMonth; m_nYear = nYear; } // attention ! this method is NOT part of CDate ostream& operator<<(ostream &mystream, const CDate& date) { return date.OutStream(mystream); } // used to perform proper display in derived classes ostream& CDate::OutStream(ostream& mystream, bool bDebug) const { if (!bDebug) { mystream << m_nDay << "." << m_nMonth << "." << m_nYear; } else { mystream << "DEBUG info for '" << ClassnameOf() << "'" << endl << " m_nDay=" << m_nDay << " m_nMonth=" << m_nMonth << " m_nYear=" << m_nYear; } return mystream; } // return current date CDate CDate::GetToday() { CDate dtReturn; // the following code is taken from MSDN // use system functions to get the current date as UTC time_t secondsSince1970; time(&secondsSince1970); // convert UTC to local time zone struct tm *localTime; localTime = localtime(&secondsSince1970); // store retrieved date dtReturn.m_nDay = localTime->tm_mday; dtReturn.m_nMonth = localTime->tm_mon + 1; dtReturn.m_nYear = localTime->tm_year + 1900; return dtReturn; } // validate a date bool CDate::IsValid() const { // validate month if (m_nMonth < JANUARY || m_nMonth > DECEMBER) return false; // days per month, february ma(r)y vary !!! int nDaysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // adjust days of february if (IsLeapYear(m_nYear)) nDaysPerMonth[FEBRUARY]++; // validate day if (m_nDay < 1 || m_nDay > nDaysPerMonth[m_nMonth]) return false; // day and month are valid return true; } // determine whether it is a leap year bool CDate::IsLeapYear(int nYear) { // used to speed up code, may be deleted if (nYear % 4 != 0) return false; // algorithm taken from MSDN, just converted from VBA to C++ if (nYear % 400 == 0) return true; if (nYear % 100 == 0) return false; if (nYear % 4 == 0) return true; // this line won't be executed because of optimization (see above) return false; } // copy constructor CDate& CDate::operator =(const CDate &date) { m_nDay = date.m_nDay; m_nMonth = date.m_nMonth; m_nYear = date.m_nYear; // m_bDebug is not copied ! return *this; } // virtual, see operator= bool CDate::Copy(const CDate *date) { // invalid class if (date == NULL || date == this) return false; // use non virtual reference based copy // return value isn't needed operator=(*date); // we're done return true; } // compare two dates bool CDate::operator ==(const CDate &date) const { // m_bDebug is not neccessary return (m_nDay == date.m_nDay && m_nMonth == date.m_nMonth && m_nYear == date.m_nYear); } // virtual, see operator== bool CDate::EqualValue(CDate *date) const { // invalid class if (date == NULL) return false; // use non virtual reference based copy return operator==(*date); } // set attributes, returns validility of date inline bool CDate::SetDay(int nDay) { m_nDay = nDay; return IsValid(); } inline bool CDate::SetMonth(int nMonth) { m_nMonth = nMonth; return IsValid(); } inline bool CDate::SetYear(int nYear) { m_nYear = nYear; return IsValid(); } // return attributes inline int CDate::GetDay() const { return m_nDay; } inline int CDate::GetMonth() const { return m_nMonth; } inline int CDate::GetYear() const { return m_nYear; }