Add time duration to C++ timepoint
Solution 1
If you want to add five hours to startTimePoint
, it's boringly simple:
startTimePoint += hours(5); // from the alias std::chrono::hours
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;
}
Related videos on Youtube
Harry Boy
Updated on March 12, 2020Comments
-
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 about 7 yearsOr, change
system_clock::time_point
tosteady_clock::time_point
. -
BmyGuest over 3 yearsI 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...