#ifndef TIME24_CLASS #define TIME24_CLASS #include #include #include "d_except.h" // for rangeError exception using namespace std; #ifdef _MSC_VER class time24; time24 operator+ (const time24& lhs, const time24& rhs); time24 operator+ (const time24& lhs, int min); time24 operator+ (int min, const time24& rhs); time24 operator- (const time24& lhs, const time24& rhs); bool operator== (const time24& lhs, const time24& rhs); bool operator< (const time24& lhs, const time24& rhs); istream& operator>> (istream& istr, time24 &r); ostream& operator<< (ostream& ostr, const time24& r); #endif // _MSC_VER class time24 { public: time24(int h = 0, int m = 0); // constructor initializes hour and minute void addTime(int m); // update time by adding m minutes to the current time // Precondition: m must be >= 0 // Postcondition: The new time is m minutes later time24 duration(const time24& t); // return the length of time from the current time to some later // time t as a time24 value // Precondition: time t must not be earlier than the current time. // if it is, throw a rangeError exception void readTime(); // input from the keyboard time in the form hh:mm // Postcondition: Assign value hh to hour and mm to minute and // adjust units to the proper range. void writeTime() const; // display on the screen the current time in the form hh:mm int getHour() const; // return the hour value for the current time int getMinute() const; // return the minute value for the current time // THESE FUNCTIONS ARE DISCUSSED IN CHAPTER 2 ON OPERATOR // OVERLOADING friend bool operator== (const time24& lhs, const time24& rhs); friend bool operator< (const time24& lhs, const time24& rhs); friend time24 operator+ (const time24& lhs, const time24& rhs); // form and return lhs + rhs friend time24 operator+ (const time24& lhs, int min); // form and return lhs + min // Precondition: min must be >= 0 friend time24 operator+ (int min, const time24& rhs); // form and return min + rhs // Precondition: min must be >= 0 friend time24 operator- (const time24& lhs, const time24& rhs); // form and return lhs - rhs // Precondition: lhs >= rhs. if not, throw a rangeError exception time24& operator+= (const time24& rhs); // current object = current object + rhs // Postcondition: the time increases by the value of rhs time24& operator+= (int min); // current object = current object + min // Precondition: min must be >= 0 // Postcondition: the time increases by min minutes friend istream& operator>> (istream& istr, time24& t); // input t in the format hh:mm. may omit the leading digit // if hours or minutes < 10 friend ostream& operator<< (ostream& ostr, const time24& t); // output t in the format hh:mm. always include two digits // for the minute (e.g. 15:07). hours before 12 use 1 digit // and precede the hour by a blank (e.g. " 7:15") private: int hour, minute; // data members // utility function sets the hour value in the range 0 to 23 // and the minute value in the range 0 to 50 void normalizeTime(); }; // *********************************************************** // time24 class implementation // *********************************************************** // set minute and hour within their proper ranges void time24::normalizeTime() { int extraHours = minute / 60; // set minute in range 0 to 59 minute %= 60; // update hour. set in range 0 to 23 hour = (hour + extraHours) % 24; } // constructor. initialize time data time24::time24(int h, int m) : hour(h), minute(m) { // put hour and minute in correct range normalizeTime(); } // add m minutes to the time void time24::addTime(int m) { // add m to minute. minute may exceed 59, so normalize minute += m; normalizeTime(); } time24 time24::duration(const time24& t) { // convert current time and time t to minutes int currTime = hour * 60 + minute; int tTime = t.hour * 60 + t.minute; // if t is earlier than the current time, throw an exception if (tTime < currTime) throw rangeError( "time24 duration(): argument is an earlier time"); else // create an anonymous object as the return value return time24(0, tTime-currTime); } void time24::readTime() { char colonSeparator; cin >> hour >> colonSeparator >> minute; // make sure hour and minute are in range normalizeTime(); } // output time in the format : void time24::writeTime() const { // the implementation uses stream handling functions // not discussed in the book. consult your compiler // help system for details // save current format flags and fill character long currentFlags = cout.flags(); char currentFill = cout.fill(); // set fill char to ' ' and enable right justification cout.fill(' '); cout.setf(ios::right,ios::adjustfield); // output the hour cout << setw(2) << hour << ':'; // set fill char to '0' and output the minute cout.fill('0'); cout << setw(2) << minute << " "; // restore the fill char and the format flags cout.fill(currentFill); cout.setf(currentFlags); } int time24::getHour() const { return hour; } int time24::getMinute() const { return minute; } // compare hours and minutes bool operator== (const time24& lhs, const time24& rhs) { return lhs.hour == rhs.hour && lhs.minute == rhs.minute; } // convert the hour and minute values for each operand to // minutes. compare lhs in minutes with rhs in minutes bool operator< (const time24& lhs, const time24& rhs) { return (lhs.hour*60 + lhs.minute) < (rhs.hour*60 + rhs.minute); } // create an anonymous object with hour = lhs.hour + rhs.hour // and minute = lhs.minute+rhs.minute. time24 operator+ (const time24& lhs, const time24& rhs) { return time24(lhs.hour+rhs.hour, lhs.minute+rhs.minute); } // create an anonymous object with hour = lhs.hour and // minute = lhs.minute + min. time24 operator+ (const time24& lhs, int min){ return time24(lhs.hour, lhs.minute + min); } // return the value rhs + min that is computed by // time24 operator+ (const time24& lhs, int min) time24 operator+ (int min, const time24& rhs) { return rhs + min; } // using the < operator, check whether lhs < rhs is true. if so // terminate; otherwise return a time24 result built // using the constructor time24 operator- (const time24& lhs, const time24& rhs) { if (lhs < rhs) throw rangeError("time24 operator-: Cannot subtract later from earlier time"); // convert each object to minutes and compute the // difference in minutes. return the time24 object // having 0 as hours and the value of the difference // as minutes return time24(0, (lhs.hour*60 + lhs.minute) - (rhs.hour*60 + rhs.minute)); } // implement += by using addition with operands *this and rhs time24& time24::operator+= (const time24& rhs) { // add *this and rhs using overloaded + operator *this = *this + rhs; // return a reference to the current object return *this; } // implement += by using addition with operands *this and min time24& time24::operator+= (int min) { // add *this and min using overloaded + operator *this = *this + min; // return a reference to the current object return *this; } // overload stream operator >>. input has the form // hour:minute istream& operator>> (istream& istr, time24& t) { char separatorChar; istr >> t.hour >> separatorChar >> t.minute; // make sure hour and minute are in range t.normalizeTime(); // return the stream return istr; } // overload stream operator <<. output in the form // hour:minute ostream& operator<< (ostream& ostr, const time24& t) { // the implementation uses stream handling functions // not discussed in the book. consult your compiler // help system for details // save current format flags and fill character long currentFlags = ostr.flags(); char currentFill = ostr.fill(); // set fill char to ' ' and enable right justification ostr.fill(' '); ostr.setf(ios::right,ios::adjustfield); // output the hour ostr << setw(2) << t.hour << ':'; // set fill char to '0' and output the minute ostr.fill('0'); ostr << setw(2) << t.minute; // restore the fill char and the format flags ostr.fill(currentFill); ostr.setf(currentFlags); return ostr; } #endif // TIME24_CLASS