Adding and Subtracting Time
Asked Answered
L

6

9

I am new to C++ - I wanted to make a program to add and subtract time using a HH:MM format. Sample Input:

12:00 + 3:00 - 6:00

Sample Output:

9:00

Another Sample Input:

9:00 + 8:00 + 13:00 - 2:25

Sample Output:

27:35

How do I got about this? I was thinking convert everything down to seconds and then apply the math then use a modulus 60 function to return the time. Any help on building such a program?

Lobbyist answered 22/12, 2012 at 4:58 Comment(3)
Seems like you've got it. Good luck!.Zeigler
The only issue is that I need to use the following header file and time classLobbyist
you don't 'need' the time class for this.. that would be a waste of time.. (no pun intended).. what you require is pretty basic and can be easily achieved with normal arithmetic operations.Arthrospore
C
3

You need to consider what you mean by 'time'. There are two concepts, time points and durations. It doesn't make any sense to add time points together. It does make sense to add and subtract durations (resulting in a duration), and it makes sense to add and subtract a duration with a time point (resulting in a new time point offset from the original). It also makes sense to subtract one time point from another, producing the intervening duration.

Many time APIs don't do a great job differentiating between the two concepts, but the standard C++ <chrono> library does.

Here's some code that abuses the C tm type in order to get a couple durations from the user, adds them together, and then abuses tm again to output the result.

#include <iostream> // cout, cin
#include <iomanip>  // get_time, put_time
#include <chrono>   // hours, minutes, duration_cast

int main() {
    // input, get a couple durations to do arithmetic on
    // technically std::tm represents a time point and get_time is supposed to
    // parse a time point, but we treat the results as a duration
    std::tm t;
    std::cin >> std::get_time(&t, "%H:%M");

    auto duration1 = std::chrono::hours(t.tm_hour) + std::chrono::minutes(t.tm_min);

    std::cin >> std::get_time(&t, "%H:%M");
    auto duration2 = std::chrono::hours(t.tm_hour) + std::chrono::minutes(t.tm_min);

    // do the arithmetic
    auto sum = duration1 + duration2;

    // output
    auto hours   = std::chrono::duration_cast<std::chrono::hours>(sum);
    auto minutes = std::chrono::duration_cast<std::chrono::minutes>(sum - hours);

    t.tm_hour = hours.count();
    t.tm_min  = minutes.count();

    std::cout << std::put_time(&t, "%H:%M") << '\n';
}
Canonist answered 22/12, 2012 at 8:59 Comment(1)
Doesn't it make sense to subtract one time point from another, in order to compute the time-interval between the two?Prophetic
B
2

I wanted to share some code as the question requests for a program as a newbie to C++. This is not the perfect code but may be a good hands-on for someone new to C++. It will address the addition and subtraction of time stamps. i.e You may need to add additional validations and can be extended to represent days, seconds and milliseconds...

#include <iostream>
#include <string>

using namespace std;

/// Represents the timestamp in HH:MM format
class Time {
public:
    // Construct the time with hours and minutes
    Time(size_t hours, size_t mins);

    // Construct the time using a string
    Time(const string& str);

    // Destructor
    ~Time() {}

    // Add a given time
    Time operator + (const Time& rTime) const;

    // Subtract a given time
    Time operator - (const Time& rTime) const;

    // Get the members
    int Hours() const { return m_Hours; }
    int Minutes() const { return m_Minutes; }

    // Get the time as a string in HH:MM format
    string TimeStr();   

private:
    // Private members
    int m_Hours;    // Hours
    int m_Minutes;  // Minutes
};

// Constructor
Time::Time(size_t hours, size_t mins) {
    if (hours >= 60 || mins >= 60) {
        cout << "Invalid input" << endl;    
        exit(0);
    }

    // Update the members
    m_Hours = hours;
    m_Minutes = mins;
}

// Add the given time to this
Time Time::operator + (const Time& rTime) const {
    // Construct the time
    int nTotalMinutes(m_Minutes + rTime.Minutes());
    int nMinutes(nTotalMinutes % 60);
    int nHours(nTotalMinutes/60 + (m_Hours + rTime.Hours()));

    // Return the constructed time
    return Time(nHours, nMinutes);
}

// Construct the time using a string
Time::Time(const string& str) {
    if(str.length() != 5 || str[2] != ':') {
        cout << "Invalid time string. Expected format [HH:MM]" << endl;
        exit(0);
    }

    // Update the members
    m_Hours  = stoi(str.substr(0, 2));  
    m_Minutes = stoi(str.substr(3, 2)); 
}

// Substact the given time from this
Time Time::operator - (const Time& rTime) const {
    // Get the diff in seconds
    int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

    int nHours(nDiff/3600);
    int nMins((nDiff%3600)/60);

    // Return the constructed time
    return Time(nHours, nMins);
}

// Get the time in "HH:MM" format
string Time::TimeStr() {
    // Fill with a leading 0 if HH/MM are in single digits
    return ((m_Hours < 10) ? string("0") + to_string(m_Hours) : to_string(m_Hours))
           + string(":")
           + ((m_Minutes < 10) ? string("0") + to_string(m_Minutes) : to_string(m_Minutes));
}


int main() {
    Time time1("09:00");    // Time 1
    Time time2("08:00");    // Time 2
    Time time3("13:00");    // Time 3
    Time time4("02:25");    // Time 4

    //time1 + time 2 + time3 - time4
    cout << (time1 + time2 + time3 - time4).TimeStr() << endl;

    return 0;
}

Output: 27:35

Broussard answered 21/6, 2017 at 14:34 Comment(0)
A
1

this(part 1) and this(part 2) should be exactly what you want..

you get a clear explanation and the author steps through the code line by line and he also uses best practice.

Arthrospore answered 22/12, 2012 at 5:7 Comment(4)
So, what is the best practice? Are you going to describe it here in the answer? (Otherwise this is a link-only answer, which is discouraged.)Brachylogy
..by best practice, i was a bit vague i guess.. but to me its organization and presentation, he clearly outlined what he wanted and the code is well laid out in separate files.. etc and in this case, there was nothing else i could have typed that wouldn't have been thoroughly explained via the link(s)..Arthrospore
Please include some code next time. Merely linking to a 20-minute video is not a good way to answer a question.Dawnedawson
@LorienBrune Ha, I was very new to SE at the time (almost 6 years ago), funnily enough I'm a moderator now, just goes to show how much one can learn. Thanks, I'll flag this for deletion.Arthrospore
E
1

Use Chrono. I was surprised at how much can be done easily with it. https://www.youtube.com/watch?v=P32hvk8b13M

Eade answered 30/6, 2024 at 14:8 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewFavoritism
H
0

The simplest solution is just to parse the input into integers (using std::istream), insert them into a tm (type defined in <time.h>), and call mktime (also in <time.h>). (There is some new stuff for handling time in C++11, but I'm not really familiar with it yet.)

Hellebore answered 22/12, 2012 at 8:30 Comment(0)
C
0

I found a little problem in this line:

int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

In the nDiff( ... ) the argument need to be the absolute value! nDiff( abs(...) )

When you have for example:

Time time1("01:00");
Time time2("02:00");
cout << ( time1 - time2 ).TimeStr() << endl;

Output:

hours = 18446744073709551615
Invalid input

For the case:

cout << ( time1 + time2 ).TimeStr() << endl;

Output:

03:00

That conclusion is just change:

int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

for this one:

int nDiff( abs(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60) ) );

and add this the header in the code:

#include <cstdlib> // function abs()

In this way the code can work very well. :)

Happy coding! Cheers.

Combings answered 18/4, 2020 at 0:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.