/////////////////////////////////////////////////////////// // Softwarebauelemente II, Aufgabe C1.1 // // author: Stephan Brumme // last changes: July 3, 2001 #include "Date.h" // we are using OS-specific date/time operations #include #include #include using namespace std; // constructor, default value is current date and time CDate::CDate() { GetToday(m_nDay, m_nMonth, m_nYear, m_nHour, m_nMinute, m_nSecond); } // copy constructor CDate::CDate(const CDate &date) { operator=(date); } // set user defined date at construction time CDate::CDate(unsigned int nDay, unsigned int nMonth, unsigned int nYear, unsigned int nHour, unsigned int nMinute, unsigned int nSecond) { // store date m_nDay = nDay; m_nMonth = nMonth; m_nYear = nYear; // store time m_nHour = nHour; m_nMinute = nMinute; m_nSecond = nSecond; } // show attributes string CDate::Show() const { // check invariance if (!ClassInvariant()) return ""; ostringstream strOutput; strOutput << setw(2) << setfill('0') << m_nDay << "." << setw(2) << setfill('0') << m_nMonth << "." << m_nYear << " - " << setw(2) << setfill('0') << m_nHour<< ":" << setw(2) << setfill('0') << m_nMinute << ":" << setw(2) << setfill('0') << m_nSecond; return strOutput.str(); } // shows all internal attributes string CDate::ShowDebug() const { ostringstream strOutput; strOutput << "DEBUG info for 'CDate'" << endl << " m_nDay = " << m_nDay << endl << " m_nMonth = " << m_nMonth << endl << " m_nYear = " << m_nYear << endl << " m_nHour = " << m_nHour << endl << " m_nMinute = " << m_nMinute << endl << " m_nSecond = " << m_nSecond << endl; return strOutput.str(); } // return current date void CDate::GetToday(unsigned int &nDay, unsigned int &nMonth, unsigned int &nYear, unsigned int &nHour, unsigned int &nMinute, unsigned int &nSecond) { // the following code is basically 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 nDay = localTime->tm_mday; nMonth = localTime->tm_mon + 1; nYear = localTime->tm_year + 1900; // store time nHour = localTime->tm_hour; nMinute = localTime->tm_min; nSecond = localTime->tm_sec; } // validate a date bool CDate::ClassInvariant() const { // validate month if (m_nMonth < JANUARY || m_nMonth > DECEMBER) return false; // days per month, february may vary, note that array starts with 0, not JANUARY unsigned int nDaysPerMonth[] = {0, 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 // now check the time if (m_nHour < 0 || m_nHour > 23) return false; if (m_nMinute < 0 || m_nMinute > 59) return false; if (m_nSecond < 0 || m_nSecond > 59) return false; // instance must be valid now return true; } // determine whether it is a leap year bool CDate::IsLeapYear(unsigned 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) { // date m_nDay = date.m_nDay; m_nMonth = date.m_nMonth; m_nYear = date.m_nYear; // time m_nHour = date.m_nHour; m_nMinute = date.m_nMinute; m_nSecond = date.m_nSecond; return *this; } // virtual, see operator= bool CDate::Copy(const CBasicClass *pClass) { // cast to CDate const CDate *date = dynamic_cast(pClass); // invalid class (is NULL when pClass is not a CDate) 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 { // compare date and time attributes return (m_nDay == date.m_nDay && m_nMonth == date.m_nMonth && m_nYear == date.m_nYear && m_nHour == date.m_nHour && m_nMinute == date.m_nMinute && m_nSecond == date.m_nSecond); } // virtual, see operator== bool CDate::EqualValue(const CBasicClass *pClass) const { // cast to CDate const CDate *date = dynamic_cast(pClass); // invalid class (is NULL when pClass is not a CDate) if (date == NULL) return false; // use non virtual reference based copy return operator==(*date); } // set attributes, returns validility of date void CDate::SetDay(unsigned int nDay) { m_nDay = nDay; } void CDate::SetMonth(unsigned int nMonth) { m_nMonth = nMonth; } void CDate::SetYear(unsigned int nYear) { m_nYear = nYear; } void CDate::SetHour(unsigned int nHour) { m_nHour = nHour; } void CDate::SetMinute(unsigned int nMinute) { m_nMinute = nMinute; } void CDate::SetSecond(unsigned int nSecond) { m_nSecond = nSecond; } // return attributes unsigned int CDate::GetDay() const { return m_nDay; } unsigned int CDate::GetMonth() const { return m_nMonth; } unsigned int CDate::GetYear() const { return m_nYear; } unsigned int CDate::GetHour() const { return m_nHour; } unsigned int CDate::GetMinute() const { return m_nMinute; } unsigned int CDate::GetSecond() const { return m_nSecond; }