Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Program uses overloaded binary operators to add and subtract time.  Need to add code to prevent time from becoming negative when subtracting.

Posted on 2004-09-26
8
Medium Priority
?
397 Views
Last Modified: 2010-04-01
This program is properly adding and subtracting time from a given time.  However, it returns a negative time if you subtract a larger number than the current hour.  I need help to add some code to prevent this.  Here is my program:

#include <iostream>
#include <iomanip>
using namespace std;

class Time
{
private:
    int hour;
    int minute;
    int second;
public:
    // Default constructor
    Time(int h=0, int m=0, int s=0) { set(h, m, s); }
    // Overload the binary += operator
    void operator+=(Time &t);
      void operator-=(Time &t);
    void display() const
    {
        cout << setw(2) << setfill('0') << hour << ":"
             << setw(2) << setfill('0') << minute << ":"
             << setw(2) << setfill('0') << second << endl;
    }
    void set(int h=0, int m=0, int s=0);
};


int main()
{
    Time t1, t2, t3;
    t1.set(23, 30, 15);
      cout<<"The original time is:\n";
      t1.display();
    t2.set(12, 01, 46);
    t1 += t2;
      cout<<"The time with 12 hours added is:\n";
    t1.display();
      t3.set(15, 00, 00);
      cout<<"The time with 15 hours subtracted is:\n";
      t1 -= t3;
      t1.display();
    return 0;
}

void Time::operator +=(Time &t)
{
    // Use the set function to take care of the addition
    set(hour + t.hour, minute + t.minute, second + t.second);
}

void Time::operator -=(Time &t)
{
      set(hour - t.hour, minute - t.minute, second - t.second);
}

void Time::set(int h, int m, int s)
{
    second = s % 60;
    m += s / 60;
    minute = m % 60;
    h += m / 60;
    hour = h % 24;
}
0
Comment
Question by:coririzzo
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 19

Accepted Solution

by:
drichards earned 2000 total points
ID: 12157120
Don't you also have the same problem with minutes and seconds?  Something like this maybe:
--------------------------------------------------------------
void Time::set(int h, int m, int s)
{
    if ( s < 0 )
    {
        second = (s % 60) + 60;
        m += (s/60 -1);
    }
    else
    {
        second = s % 60;
        m += s/60;
    }
    if ( m < 0 )
    {
        minute = (m % 60) + 60;
        h += (s/60 - 1);
    }
    else
    {
        minute = m % 60;
        h += m/60;
    }
    hour = h % 24;
    if ( hour < 0 ) hour += 24;
}--------------------------------------------
0
 
LVL 19

Expert Comment

by:drichards
ID: 12157168
A bit more compact:

void Time::set(int h, int m, int s)
{
    int exs = (s < 0 ? 60 : 0);
    second = (s % 60) + exs;
    m += (s-exs)/60;

    exs = (m < 0 ? 60 : 0);
    minute = (m % 60) + exs;
    h += (m-exs)/60;

    hour = h % 24;
    if ( hour < 0 ) hour += 24;
}
0
 

Author Comment

by:coririzzo
ID: 12159411
What if the set time function calls separate functions for setHour, set Minute, and set Second?  In this case the setHour works fine, but the compiler says that h is an undeclared identifier in setMinute and m is an undeclared identifier in setSecond.  How can I pass the "extra" time to these functions?  I can post another question for more points if necessary.  Thanks!

Time::Time( int hr, int min, int sec )
{
   setTime( hr, min, sec );

} // end Time constructor

Time &Time::setTime( int h, int m, int s )
{
   setSecond( s );
   setMinute( m );
   setHour( h );
   return *this;   // enables cascading
}

Time &Time::setHour( int h )
{
    hour = h % 24;
    if (hour < 0 ) hour += 24;
    return *this;   // enables cascading
}

Time &Time::setMinute( int m )
{
      if ( m < 0 )
      {
            h += (s/60 -1);
            minute = (m % 60) + 60;
      }
      else
      {
            h += m/60;
            minute = m % 60;
      }
   return *this;   // enables cascading
}

Time &Time::setSecond( int s )
{
      if (s < 0)
      {
            second = (s % 60) + 60;
            m += (s/60 -1);
      }
      else
      {
            second = s % 60;
            m+= s/60;
      }
   return *this;   // enables cascading
}
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 19

Expert Comment

by:drichards
ID: 12160274
What does it mean to set one of the components but not the others?  One of these should be correct.  Depends whether you keep the current values for the parts you are not setting or not.

Zeroing out the other parts of the time:
-----------------------------------------
Time &Time::setHour( int h )
{
    SetTime(h, 0, 0);
    return *this;   // enables cascading
}

Time &Time::setMinute( int m )
{
    SetTime(0, m, 0);
    return *this;   // enables cascading
}

Time &Time::setSecond( int s )
{
    SetTime(0, 0, s);
    return *this;   // enables cascading
}
-------------------------------------------

or keeping the other parts:

-------------------------------------------
Time &Time::setHour( int h )
{
    SetTime(h, minute, second);
    return *this;   // enables cascading
}

Time &Time::setMinute( int m )
{
    SetTime(hour, m, second);
    return *this;   // enables cascading
}

Time &Time::setSecond( int s )
{
    SetTime(hour, minute, s);
    return *this;   // enables cascading
}
0
 

Author Comment

by:coririzzo
ID: 12166298
setTime calls the functions setHour, setMinute, and setSecond.  So it doesn't work to call setTime within setHour (or setMinute or set Second).  This causes a compiler exception error and stack overflow.
0
 
LVL 19

Expert Comment

by:drichards
ID: 12166521
I didn't notice that you changed setTime.  You're better off doing it the opposite way - have setHour, etc. call setTime.  SetTime controls all three parts of the time.   Otherwise, setSecond will have to touch the minutes and setMinute will have to touch the hours.  May as well just defer everything to the one place that takes care of it all.

In fact, you really can't do it easily the way you've got things defined.  Look carefully:

'setTime' takes h, m ,s as parameters.  When you call 'setSecond' you may have overflow that needs to be added to the minutes.  Unfortunately, when you get back to 'setTime' to do 'setMinute', you have lost this information and you can't update m properly.  With your functions defined as they are, there's no simple way to reconcile this.  I'd put 'setTime' back the way it way and have the other three call it.

0
 

Author Comment

by:coririzzo
ID: 12176109
Thanks for all your input on this.  Unfortunately, it is homework, and I have to use code from the textbook a a base.  It uses the setTime calling setHour, setMinute, and setSecond.  I have it working, but without your neat error checking stuff in there.  A couple of people at work are going to look at it, so maybe I'll get it figured out.
0
 
LVL 19

Expert Comment

by:drichards
ID: 12181228
It sounds to me then that the setters should not accept values outside acceptable range:  minutes and seconds should be from 0 to 59 and hours from 0 to 23.  That keeps the normalozation logic in the add and subtract operations rather than in the setters.  Seems simpler.Tring to set the seconds to 75 would be illegal.  This eliminates all of the complexity.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question