#ifndef __DateClass #define __DateClass #include #include // The DATE class is designed to represent any date between 1/1/1800 // and 31/12/2099. A date is stored numerically as a day of the month, // a month of the year, a year number, and the number of days since // 1/1/1800. // The class has two private member functions - for internal use only. // setdaynum Computes the number of days since 1/1/1800. This // function is used only in the constructor to set daynum // // valid Returns a 1 to indicate a date being constructed is // valid (and 0 to indicate an invalid date). This function // is used only in the constructor. When an error is // detected, valid displays an error message. The arguments // are a day number, a month number, and a year number. // The class has two constructors. The default copy constructor and // the default destructor are used. // // One constructor takes a day number, a month number, and a year number // as arguments and uses them to intialize the date. The other constructor // takes no arguments and initializes the date to the starting date // 1/1/1800. // The class has two named functions, five operator functions, and one // friend function. // // weekday Returns the day number within a week (a number from 0 to 6) // where 0 indicates Sunday, 1 Monday, ... and 6 Saturday. // // monthday Returns the day number within a month. // // operator= Assigns the rhs date to the lhs date. // // operator- Returns a day count as the difference between two dates. // The argument (the rhs) is a date. // // operator+ Returns a date that is some number of days after the lhs // date. The argument (the rhs) is an int. // // operator== Returns a 1 if two dates are the same (a 0 otherwise). // // operator< Returns a 1 if the lhs date is less than (before) the // rhs date (a 0 otherwise). // // operator<< This friend function outputs a date in the form dd mmm yyyy // where mmm is a month name abbreviation. // class date { private: long int daynum; // Number of days since 1/1/1800 int day; // Day of month int month; // Month number (1 to 12) int year; // Year (1800 to 2099) void setdaynum (void); int valid (int, int, int); public: date (int, int, int); date (void): daynum (0), day (1), month (1), year (1800) { } int weekday (void) { return (daynum + 3) % 7; } int monthday (void) { return day; } long operator-(const date &rhs) { return daynum - rhs.daynum; } int operator== (const date &rhs) { return daynum == rhs.daynum; } int operator< (const date &rhs) { return daynum < rhs.daynum; } date & operator= (const date &); date operator+ (int); friend ostream & operator<< (ostream &, date &); }; void date::setdaynum (void) { // setdaynum computes the daynum for a date const int monthstart[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; long ycount; long leapdays; ycount = year - 1800; leapdays = ycount / 4; if (((year % 4) == 0) && (month < 3) && (leapdays > 0)) leapdays--; if (leapdays > 24) leapdays--; daynum = ycount * 365 + monthstart[month - 1] + leapdays + day - 1; } int date::valid (int dd, int mm, int yy) { // valid determines if a date is valid const int monthsize[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if ((yy < 1800) || (yy > 2099)) { cout << "Invalid year: " << yy << endl; return 0; } if ((mm < 1) || (mm > 12)) { cout << "Invalid month: " << mm << endl; return 0; } if ((dd < 1) || (dd > monthsize[mm - 1])) { cout << "Invalid day: " << dd << endl; return 0; } if ((dd == 29) && (mm == 2) && (((yy % 4) != 0) || (((yy % 4) == 0) && ((yy % 400) != 0)))) { cout << "Invalid day for non-leap year." << endl; return 0; } return 1; } date::date (int dd, int mm, int yy) { // Constructor requiring arguments to build a date // Argument order: day, month, year (4-digits) if (!valid (dd, mm, yy)) { day = 1; month = 1; year = 1800; daynum = 0; } else { day = dd; month = mm; year = yy; setdaynum (); } } date & date::operator= (const date &rhs) { // Assign one date to another if (this != &rhs) // Prevent useless copy { day = rhs.day; month = rhs.month; year = rhs.year; daynum = rhs.daynum; } return *this; } date date::operator+ (int incr) { // Add some number of days to a date to get another date date temp (*this); int ms[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (incr >= 0) { if ((temp.year % 4) == 0) ms[1]++; // Adjust Feb for leapyear if (((temp.year % 100) == 0) && ((temp.year % 400) != 0)) ms[1]--; temp.day += incr; // Start by adding to day while (temp.day > ms[temp.month - 1]) { temp.day -= ms[temp.month - 1]; temp.month++; // Advance a month if (temp.month > 12) { // Move to next year ms[1] = 28; if ((temp.year % 4) == 0) ms[1]++; // Readjust Feb if (((temp.year % 100) == 0) && ((temp.year % 400) != 0)) ms[1]--; temp.year++; // Advance a year temp.month = 1; } } temp.daynum += incr; // Update daynum } else cout << "\n\nInvalid increment in + operation\n"; return temp; } ostream & operator<< (ostream &out, date &dt) { // Friend to output a date as dd mmm yyyy char *monthname[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; out << setw(2) << dt.day; out << setw(4) << monthname[dt.month - 1]; out << setw(5) << dt.year; return out; } #endif