#ifndef DATE_CLASS #define DATE_CLASS #include #include #include #include "d_except.h" using namespace std; class date { public: date (int mm=1, int dd=1, int yyyy=1900); // supply date in format MM/DD/YYYY // preconditions: 1 <= mm <= 12, // 1 <= dd <= daysInMonth() void writeShortDate () const; // output the date in the format "MM/DD/YYYY" void writeLongDate () const; // output the date in the format "month day, year" void incrementDate(int ndays); // add ndays days to the date // precondition: 0 <= ndays <= 365 int numberOfDays() const; // return the number of days into the year int getMonth() const; // return the month as integer value 1 to 12 int getDay() const; // return day of the month int getYear() const; // return the year void setMonth(int mm); // update the month // precondition: 1 <= mm <= 12 void setDay(int dd); // update the day // precondition: 1 <= dd <= daysInMonth() void setYear(int yyyy); // update the year // precondition: if the date is February 29, // yyyy must be a leap year int daysInMonth() const; // return number of days in the month bool isLeapYear() const; // is the current year a leap year (true/false) private: enum monthName {Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; // private type used by date int month, day, year; // private members that specify the date }; // constructor. month, day, year given as integer // values mm dd yyyy date::date (int mm, int dd, int yyyy): month(mm), day(dd), year(yyyy) { if (month < 1 || month > 12) throw dateError("date constructor:", month, "invalid month"); if (day <= 0 || day > daysInMonth()) throw dateError("date constructor:", day, "invalid day of month"); } // write date in the format "MM/DD/YYYY" void date::writeShortDate () const { // save current format flags and fill character long currentFlags = cout.flags(); char currentFill = cout.fill(); // enable right justification cout.setf(ios::right,ios::adjustfield); // output the month right-justified in // two character positions, blank fill cout.fill(' '); cout << setw(2) << month; // set fill char to '0' cout.fill('0'); cout << '/' << setw(2) << day << '/' << year; // restore the fill char and the format flags cout.fill(currentFill); cout.setf(currentFlags); } // write date with full month name void date::writeLongDate() const { // array begins with empty string corresponding to month 0 static string monthNames[] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; // use month as index into monthNames cout << monthNames[month] << " " << day << ", " << year; } // add ndays days to the date. ndays must be in the range // 0 <= ndays <= 365 void date::incrementDate(int ndays) { int totalDays, daysInYear = 365; int addDay; if (ndays < 0 || ndays > 365) throw dateError("date incrementDate():", ndays, "is out of range"); if(isLeapYear()) { addDay = 1; daysInYear++; } else addDay = 0; totalDays = numberOfDays() + ndays; if (totalDays/daysInYear == 1 && totalDays%daysInYear != 0) { year++; if(isLeapYear()) addDay = 1; else addDay = 0; totalDays = totalDays % daysInYear; } if (totalDays <= 31) { month = 1; day = totalDays; } else if (totalDays <= 59 + addDay) { month = 2; day = totalDays - 31; } else if (totalDays <= 90 + addDay) { month = 3; day = totalDays - (59 + addDay); } else if (totalDays <= 120 + addDay) { month = 4; day = totalDays - (90 + addDay); } else if (totalDays <= 151 + addDay) { month = 5; day = totalDays - (120 + addDay); } else if (totalDays <= 181 + addDay) { month = 6; day = totalDays - (151 + addDay); } else if (totalDays <= 212 + addDay) { month = 7; day = totalDays - (181 + addDay); } else if (totalDays <= 243 + addDay) { month = 8; day = totalDays - (212 + addDay); } else if (totalDays <= 273 + addDay) { month = 9; day = totalDays - (243 + addDay); } else if (totalDays <= 304 + addDay) { month = 10; day = totalDays - (273 + addDay); } else if (totalDays <= 334 + addDay) { month = 11; day = totalDays - (304 + addDay); } else if (totalDays <= 365 + addDay) { month = 12; day = totalDays - (334 + addDay); } } // determine the number of days into the year int date::numberOfDays() const { // assign a place holder value of 0 for monthLength[0] int monthLength[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int daysToDate = 0, i; // add up all the days in the preceding months for (i = 1; i < month; i++) daysToDate += monthLength[i]; // if year is a leap year and the month is March or later, // increment daysToDate. use member function isLeapYear() if (isLeapYear() && month > 2) daysToDate += day + 1; else daysToDate += day; return daysToDate; } // return the month as integer value 1 to 12 int date::getMonth() const { return month; } // return day of the month int date::getDay() const { return day; } // return the year int date::getYear() const { return year; } // assign a new month void date::setMonth(int mm) { // verify that mm is in the range 1 to 12 if (mm < 1 || mm > 12) throw dateError("date setMonth():", mm, "invalid month"); month = mm; } // assign a new day of current month void date::setDay(int dd) { // verify that dd is in correct range for // the current month if (dd <= 0 || dd > daysInMonth()) throw dateError("date setDay():", dd, "invalid day of month"); day = dd; } void date::setYear(int yyyy) { // assign the new year year = yyyy; // if the date is February 29, yyyy must be a // leap year if (month == 2 && day == 29 && !isLeapYear()) throw dateError("date setYear():", year, "Not a leap year. February 29 invalid"); } // return the number of days in the month int date::daysInMonth() const { int monthLength; // monthName(month) converts integer month to the // equivalent monthName object switch (monthName(month)) { case Jan: case Mar: case May: case Jul: case Aug: case Oct: case Dec: monthLength = 31; // months with 31 days break; case Apr: case Jun: case Sep: case Nov: monthLength = 30; // months with 30 days break; case Feb: if (isLeapYear()) // special case of Feb monthLength = 29; else monthLength = 28; break; } return monthLength; } // is the current year a leap year (true/false) bool date::isLeapYear() const { if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) return true; else return false; } #endif // DATE_CLASS