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??
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.
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;
}
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;
}
Thanks to Carsten's solution I managed to create function:
#include <chrono>
auto getTimeDurationMovedWith(std::chrono::hours hours2move)
{
using namespace std::chrono;
auto current_time = system_clock::now();
decltype(current_time) zeroTime; // no better solution to move time found in stackoverflow
return chrono::duration_cast<microseconds>(
current_time - zeroTime + hours(hours2move));
}
And it can be used like that:
auto tmp = getTimeDurationMovedWith(chrono::hours(-10));
cout << tmp.count() << endl;
Related
I have a bunch of tasks which are in the order of microseconds, the below code prints only until seconds (Thu Oct 21 12:48:20 2021) so comparing the values of start and finish always ends up giving 0. I want to be able to compare in the order of milliseconds and microseconds. Is there a function to help with this?
Also, is there a way to convert uint64_t current1 = std::chrono::system_clock::now().time_since_epoch().count(); to time_t to print out the current time based on the count()?
const auto p1 = std::chrono::system_clock::now();
std::time_t now = std::chrono::system_clock::to_time_t(p1);
std::cout << "now: " << std::ctime(&now);
I recommend skipping the C timing API entirely. It is error-prone and doesn't handle sub-second precision.
If UTC (as opposed to local time) is ok, then there is a header-only, open-source preview of C++20 that works with C++11/14/17:
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using date::operator<<;
const auto p1 = std::chrono::system_clock::now();
std::cout << "now: " << p1 << '\n';
}
Output:
now: 2021-10-21 20:28:15.754423
To port the above program to C++20 (which is already shipping in the latest Visual Studio), just drop the #include "date/date.h" and using date::operator<<;.
If you need local time, that can be also be had in C++20 (shipping in VS), but the open-source preview of C++20 is no longer header only. There exists one source file that needs to be compiled, and depending on your needs, might require a download of the IANA tz database.
#include "date/tz.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
const auto p1 = system_clock::now();
std::cout << "now: " << zoned_time{current_zone(), p1} << '\n';
}
Output:
now: 2021-10-21 16:28:15.754423 EDT
The above syntax assumes C++17. For C++11/14 the template parameter for zoned_time needs to be specified: zoned_time<system_clock::duration>.
The above program ports to C++20 by dropping #include "date/tz.h" and using namespace date;.
In either program you can truncate to millisecond precision with:
const auto p1 = floor<milliseconds>(system_clock::now());
time_t is usually an integer specifying (whole) seconds.
You could get the millseconds by subtracting the whole-second time_t from now:
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
p1 - std::chrono::system_clock::from_time_t(now)).count();
or using operator%:
auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>p1)
.time_since_epoch() % std::chrono::seconds(1);
std::cout << ms.count();
Example how you could do the formatting:
#include <chrono>
#include <iostream>
#include <iomanip>
int main() {
using Clock = std::chrono::system_clock;
using Precision = std::chrono::milliseconds;
auto time_point = Clock::now();
// extract std::time_t from time_point
std::time_t t = Clock::to_time_t(time_point);
// output the part supported by std::tm
std::cout << std::put_time(std::localtime(&t), "%FT%T."); // select format here
// get duration since epoch
auto dur = time_point.time_since_epoch();
// extract the sub second part from the duration since epoch
auto ss =
std::chrono::duration_cast<Precision>(dur) % std::chrono::seconds{1};
// output the millisecond part
std::cout << std::setfill('0') << std::setw(3) << ss.count();
}
Let's say, I have following duration value:
auto duration=12h+15min+99s+99ms;
I want to know how many hours that is (as double value).
When I do auto hours=std::chrono::duration_cast<std::chrono::hours>(duration), I get hours.count() which is int. What is the right way to get the value for the whole duration expressed as double?
using namespace std::chrono;
// Create a double-based hours duration unit
using dhours = duration<double, hours::period>;
// Assign your integral-based duration to it
dhours h = 12h+15min+99s+99ms;
// Get the value
cout << h.count();
Or alternatively, simply divide your integral based duration by one double-based hours:
cout << (12h+15min+99s+99ms)/1.0h << '\n';
#include<iostream>
#include<chrono>
using namespace std::chrono_literals;
int main() {
auto duration = 12.0h+15min+99s+99ms;
std::cout << std::chrono::duration_cast<std::chrono::duration<long double,std::ratio<3600,1>>>(duration).count();
}
I want to exit While loop, when variable "duration" reaches 5 sec.
Variable "duration" always =0
#include <iostream>
#include <Windows.h>
#include <chrono>
using namespace std;
DOUBLE duration;
int main()
{
using clock = std::chrono::system_clock;
using sec = std::chrono::duration <double>;
const auto before = clock::now();
while (duration < 5.0)
{
const auto after = clock::now();
const sec duration = after - before;
std::cout << "It took " << duration.count() << "s" << std::endl;
}
std::cout << "After While Loop "; //Never reaches this line!!!!!
return 0;
}
Actual output:.
.
it took 9.50618s
it tool 9.50642s
.
I expected while loop to exit at 5.0 or higher.
display variable always shows 0.
You are using two separate variables named duration.
using sec = std::chrono::duration <double>; // number 1
const auto before = clock::now();
while (duration < 5.0) // checking number 1, which is not changed during looping
{
const auto after = clock::now();
const sec duration = after - before; // number 2, created afresh in each iteration
std::cout << "It took " << duration.count() << "s" << std::endl;
}
So, what you are checking in the loop condition is not what gets changed in the loop body.
You have two variables called duration:
DOUBLE duration;
and in while loop:
const sec duration = after - before;
During evaluation of while statement you are checking the first one that is never set or changed.
Inside while loop body you're creating a new variable that shadows global variable. See https://en.wikipedia.org/wiki/Variable_shadowing
Insead you shouldn't declare a new variable but use one declared before entering to the while loop.
There are two issues here:
Declaring a local variable with the same name that of the global variable makes them two separate entities, which may get quiet confusing. This phenomenon is called as Variable shadowing.
You are comparing the duration variable which is actually an object of class sec and not an integer or float. So, for comparing the value in duration just do duration.count() to make it comparable to integer or float values.
Here, in your code, the global duration variable is never changed because you are declaring a new variable inside the while loop. The duration variable that is been checked in the while condition is the global duration variable but you expect it to be the duration variable inside the loop.
There are two possible solutions:
Either make the two duration variables the same.
Or break the while(1) loop when the duration variable hold value >= 5,
Solution 1 code looks like this:
#include <iostream>
#include <Windows.h>
#include <chrono>
using namespace std;
int main()
{
using clock = std::chrono::system_clock;
using sec = std::chrono::duration <double>;
sec duration;
const auto before = clock::now();
while (duration.count() < 5.0)
{
const auto after = clock::now();
duration = after - before;
std::cout << "It took " << duration.count() << "s" << std::endl;
}
std::cout << "After While Loop "; //Never reaches this line!!!!!
return 0;
}
Solution 2 code looks like this:
#include <iostream>
#include <Windows.h>
#include <chrono>
using namespace std;
int main()
{
using clock = std::chrono::system_clock;
using sec = std::chrono::duration <double>;
const auto before = clock::now();
while (1) // Soln 1: while(1)
{
const auto after = clock::now();
const sec duration = after - before;
std::cout << "It took " << duration.count() << "s" << std::endl;
if(duration.count() >= 5)
break;
}
std::cout << "After While Loop "; //Never reaches this line!!!!!
return 0;
}
How should I proceed to convert std::chrono::minutes::rep type value to hours representation.
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main() {
minutes::rep time = 4;
std::cout << time; // outputs as minutes, need in hours
// duration cast doesn't seems to work here because it
// needs minutes instead of minutes::rep probably
return 0;
}
minutes::rep time = 4;
std::cout << time; // outputs as minutes, need in hours
Because time is just an (implementation-defined) integer type, it has nothing to do with minutes or hours, and doesn't know anything about underlying time representation.
You want to stay in the duration realm:
minutes time{4};
auto as_hours = std::duration_cast<hours>(time);
std::cout << as_hours.count(); // prints 0
Or, likely:
auto as_hours_dbl = std::duration_cast<duration<double, hours::period>>(time);
std::cout << as_hours_dbl.count(); // prints 0.0666667
While I realize this is probably one of many identical questions, I can't seem to figure out how to properly use std::chrono. This is the solution I cobbled together.
#include <stdlib.h>
#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::milliseconds ms;
float startTime;
float getCurrentTime();
int main () {
startTime = getCurrentTime();
std::cout << "Start Time: " << startTime << "\n";
while(true) {
std::cout << getCurrentTime() - startTime << "\n";
}
return EXIT_SUCCESS;
}
float getCurrentTime() {
auto now = Time::now();
return std::chrono::duration_cast<ms>(now.time_since_epoch()).count() / 1000;
}
For some reason, this only ever returns integer values as the difference, which increments upwards at rate of 1 per second, but starting from an arbitrary, often negative, value.
What am I doing wrong? Is there a better way of doing this?
Don't escape the chrono type system until you absolutely have to. That means don't use .count() except for I/O or interacting with legacy API.
This translates to: Don't use float as time_point.
Don't bother with high_resolution_clock. This is always a typedef to either system_clock or steady_clock. For more portable code, choose one of the latter.
.
#include <iostream>
#include <chrono>
using Time = std::chrono::steady_clock;
using ms = std::chrono::milliseconds;
To start, you're going to need a duration with a representation of float and the units of seconds. This is how you do that:
using float_sec = std::chrono::duration<float>;
Next you need a time_point which uses Time as the clock, and float_sec as its duration:
using float_time_point = std::chrono::time_point<Time, float_sec>;
Now your getCurrentTime() can just return Time::now(). No fuss, no muss:
float_time_point
getCurrentTime() {
return Time::now();
}
Your main, because it has to do the I/O, is responsible for unpacking the chrono types into scalars so that it can print them:
int main () {
auto startTime = getCurrentTime();
std::cout << "Start Time: " << startTime.time_since_epoch().count() << "\n";
while(true) {
std::cout << (getCurrentTime() - startTime).count() << "\n";
}
}
This program does a similar thing. Hopefully it shows some of the capabilities (and methodology) of std::chrono:
#include <iostream>
#include <chrono>
#include <thread>
int main()
{
using namespace std::literals;
namespace chrono = std::chrono;
using clock_type = chrono::high_resolution_clock;
auto start = clock_type::now();
for(;;) {
auto first = clock_type::now();
// note use of literal - this is c++14
std::this_thread::sleep_for(500ms);
// c++11 would be this:
// std::this_thread::sleep_for(chrono::milliseconds(500));
auto last = clock_type::now();
auto interval = last - first;
auto total = last - start;
// integer cast
std::cout << "we just slept for " << chrono::duration_cast<chrono::milliseconds>(interval).count() << "ms\n";
// another integer cast
std::cout << "also known as " << chrono::duration_cast<chrono::nanoseconds>(interval).count() << "ns\n";
// floating point cast
using seconds_fp = chrono::duration<double, chrono::seconds::period>;
std::cout << "which is " << chrono::duration_cast<seconds_fp>(interval).count() << " seconds\n";
std::cout << " total time wasted: " << chrono::duration_cast<chrono::milliseconds>(total).count() << "ms\n";
std::cout << " in seconds: " << chrono::duration_cast<seconds_fp>(total).count() << "s\n";
std::cout << std::endl;
}
return 0;
}
example output:
we just slept for 503ms
also known as 503144616ns
which is 0.503145 seconds
total time wasted: 503ms
in seconds: 0.503145s
we just slept for 500ms
also known as 500799185ns
which is 0.500799 seconds
total time wasted: 1004ms
in seconds: 1.00405s
we just slept for 505ms
also known as 505114589ns
which is 0.505115 seconds
total time wasted: 1509ms
in seconds: 1.50923s
we just slept for 502ms
also known as 502478275ns
which is 0.502478 seconds
total time wasted: 2011ms
in seconds: 2.01183s