Add time duration to C++ timepoint

30,291

Solution 1

If you want to add five hours to startTimePoint, it's boringly simple:

startTimePoint += hours(5); // from the alias std::chrono::hours

Live example.

By the way, you're trying to convert a steady_clock::now() into a system_clock::time_point, which shouldn't even compile. Change the steady_clock::now() to system_clock::now() and you should be good to go.

Solution 2

Here I have used time in minutes you can go for anything that you want from the user. So the below is the simple programme using chrono

#include <iostream>
#include <chrono>
using namespace std;
int main() {
    using clock = std::chrono::system_clock;
    clock::time_point nowp = clock::now();
    cout<<"Enter the time that you want to add in minutes"<<endl;
    int time_min;
    cin>>time_min;
    cin.ignore();
    clock::time_point end = nowp + std::chrono::minutes(time_min);
    time_t nowt =  clock::to_time_t ( nowp );
    time_t endt =  clock::to_time_t ( end);
    std::cout  << " " << ctime(&nowt) << "\n";
    std::cout << ctime(&endt) << std::endl;
    return 0;
}

Solution 3

Convert time_point to duration or duration to time_point without intermediate.

It is inherently impossible to convert a time_point to duration or back directly. Many examples use time_t as intermediate, which is a fine method.

I use the method that uses the time_point 'zero' as a helper.

#include <iostream>
#include <chrono>
#include <thread>

using namespace std;

int main(int argc, char *argv[])
{
    using namespace std::chrono;
    system_clock::time_point zero;      // initialised to zero in constructor
    system_clock::time_point tp_now;    // now as time_point
    duration<int, ratio<1>> dur_now;    // now as duration
    system_clock::time_point tp_future; // calculated future as time_point

    // The objective is to sleep_until the system time is at the next 5 minutes
    // boundary (e.g. time is 09:35)

    tp_now = system_clock::now();       // What time is it now?

    cout << "tp_now  = " << tp_now.time_since_epoch().count() << endl;

    // It is not possible to assign a time_point directly to a duration.
    // but the difference between two time_points can be cast to duration
    dur_now = duration_cast<seconds>(tp_now-zero); // subtract nothing from time_point

    cout << "dur_now = " << dur_now.count() << endl;

    // Instead of using seconds granularity, I want to use 5 minutes
    // so I define a suitable type: 5 minutes in seconds
    typedef duration<int,ratio<5*60>> dur5min;

    // When assigning the time_point (ok: duration) is truncated to the nearest 5min
    dur5min min5 = duration_cast<dur5min>(tp_now-zero); // (Yes, I do it from time_point again)

    cout << "min5 ('now' in 5min units) = " << min5.count() << endl;

    // The next 5 min time point is
    min5 += dur5min{1};

    cout << "min5 += dur5min{1}         = " << min5.count() << endl;

    // It is not possible to assign a duration directly to a time_point.
    // but I can add a duration to a time_point directly
    tp_future = zero + min5;

    cout << "tp_future = " << tp_future.time_since_epoch().count() << endl;

    // to be used in e.g. sleep_until

    // std::this_thread::sleep_until(tp_future);

    return 0;
}
Share:
30,291

Related videos on Youtube

Harry Boy
Author by

Harry Boy

Updated on March 12, 2020

Comments

  • Harry Boy
    Harry Boy about 4 years

    I have a starting timepoint in milliseconds like so:

    using namespace std::chrono;
    typedef time_point<system_clock, milliseconds> MyTimePoint;
    
    MyTimePoint startTimePoint = time_point_cast<MyTimePoint::duration>(system_clock::time_point(steady_clock::now()));
    

    Now I will have a certain number of hours that I want to add or subtract to the startTimePoint.

    int numHours = -5//or 5 etc (Can be a plus or minus number)
    

    How can I add this abount of time to the original startTimePoint??

  • Benjamin R
    Benjamin R about 7 years
    Or, change system_clock::time_point to steady_clock::time_point.
  • BmyGuest
    BmyGuest over 3 years
    I wanted to add that if your time_point has a rougher time-resolution than the unit you want to add, it does not work with implicit casting and one has to do an explict cast. f.e. if you want to add nanoseconds(1) to steady_clock::now() which has a resolution of 10ns, then the above code does not work directly. This was the one missing piece of information for me today...