Adding/Subtracting time

Hello ! I'm new to this website and was wondering if I could get some help with my project. I would like to do a program that can calculate time for example the Clock system on our cellphone that the program will prompt to ask the time zone then the user should input your current time. And then the program will add +08:00 hours if your from the Philippines, -05:00 if your from New York etc. In short i would just like to know how to add/subtract time. :D Thanks for the answer :)
Last edited on
Hi,

In short i would just like to know how to add/subtract time.


Consider how you might do that on paper. Will need to treat the seconds, minutes and hours separately.

Hoe this helps :+)
Calculating with time is notoriously difficult due to timezones, leap years, daylight savings time, leap seconds and who knows what else. Fortunately there are usually library functions to handle this stuff.

The best way to handle it is the way UNIX does. Represent time as the elapsed time since some fixed point. UNIX uses seconds since 00:00:00 Jan 1, 1970 GMT. You can use the functions in ctime (http://www.cplusplus.com/reference/ctime/) to work from there.

To do something like "add 3 hours to 12:52 local time," you have to convert 12:52 local time to a time_t, add 3 hours, and convert back to local time.
I already know how to add and subtract the time. The only problem that still exist is when you try to add 5 more hours to 24:00 the result is 29:00. Is there anything that i can do to make it go back to 0 when it exceeded to 24 ?
plusjuice wrote:
Is there anything that i can do to make it go back to 0 when it exceeded to 24 ?


TheIdeasMan wrote:
Will need to treat the seconds, minutes and hours separately.


So if you have separate variables for hours, minutes and seconds, it's easy to have logic to take care of values that "overflow" their limits.

For example 40 min + 30min = 70 min.

70 min integer division 60 is 1 (hour)
70 min modulus 60 is 10 (minutes)

Note that if you are dealing with seconds, minutes, hours, and days you need to deal with them in that order because the overflow cascades upwards.

Hope this helps :+)
@TheIdeasMan,

wouldn't it be easier to deal with the time in seconds?
Adding and subtracting is easy and later you can convert it to a struct tm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <ctime>

tm operator+ ( tm uct, int span_in_minutes )
{
    // http://www.unix.com/man-page/FreeBSD/3/mktime/
    // ... the original values of the other components are not restricted to their normal ranges, and
    // will be normalized if needed.  For example, October 40 is changed into November 9, a tm_hour
    // of -1 means 1 hour before midnight, tm_mday of 0 means the day preceding the current month,
    // and tm_mon of -2 means 2 months before January of tm_year.
    uct.tm_min += span_in_minutes ;
    const auto t = std::mktime( std::addressof(uct) ) ;

    return *std::gmtime( std::addressof(t) ) ;
}

tm operator+ ( int span_in_minutes, tm uct ) { return uct + span_in_minutes ; }
tm operator- ( tm uct, int span_in_minutes ) {  return uct + -span_in_minutes ; }

int main()
{
    const auto now = std::time(nullptr) ;
    const auto uct_now = *std::gmtime( std::addressof(now) ) ;
    std::cout << "    uct: " << std::asctime( std::addressof(uct_now) ) ;

    const auto moscow_now = uct_now + 3 * 60 ; // UCT + 3:00
    std::cout << " moscow: " << std::asctime( std::addressof(moscow_now) ) ;

    const auto caracas_now = uct_now - ( 4*60 + 30 ) ; // UCT - 4:30
    std::cout << "caracas: " << std::asctime( std::addressof(caracas_now) ) ;
}

http://coliru.stacked-crooked.com/a/d1858e0bca1d0e8a
Repeating myself:
To do something like "add 3 hours to 12:52 local time," you have to convert 12:52 local time to a time_t, add 3 hours, and convert back to local time.

Use mktime() to convert from local time to a time_t. Use localtime() to convert from time_t to local time.

Technically, to manipulate calendar time in terms of hours, minutes etc., use std::tm and not std::time_t.

This is all that the standard requires:
typedef /* unspecified */ time_t; // a suitable arithmetic type capable of representing times.

Ergo, the library has double std::difftime( std::time_t, std::time_t ),
which yields the number of seconds between two std::time_t values.

On most systems, std::time_t is measured in seconds since beginning of Unix epoch, and crude seconds-based arithmetic on it would yield unsurprising results.
On POSIX systems, std::time_t is measured in seconds, and difftime is equivalent to arithmetic subtraction, but C and C++ allow fractional units for time_t.
http://en.cppreference.com/w/cpp/chrono/c/difftime
Topic archived. No new replies allowed.