ways to record time in C++ - c++

What is the most adequate way to record time in C++ (not time elapsed but time)
I am now trying something like
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
int main ()
{
using namespace std::chrono;
high_resolution_clock::time_point t1= high_resolution_clock::now();
time_t tt=system_clock::to_time_t(t1);
std::cout<<"Right now it is: " << ctime(&tt)<<std::endl;
}
but I see that this requires (or I am understanding it wrong??) that we convert from chrono to the the C way of timing with to_time so doesn't defeat the point of using chrono?
The usual examples I found while searching are about elapsed time, but I am wondering about just recording time since I am not that familiar with C++11

As of C++17 std::chrono has no facilities to easily decompose a std::chrono::system_clock::time_point into its calandar date and wall clock time other than to convert the time_point to a time_t and use the date/time formatting functionality inherited from C.
It's posible to do it using only std::chrono, but not simple. For instance something like this can get the wall clock time from a std::chrono::system_clock::time_point:
std::string time_of_day(const std::chrono::system_clock::time_point& time_point)
{
using days = std::chrono::duration<int, std::ratio<86400>>;
auto midnight = std::chrono::floor<days>(time_point);
auto time_since_midnight = time_point - midnight;
auto hours = std::chrono::floor<std::chrono::hours>(time_since_midnight);
auto minutes = std::chrono::floor<std::chrono::minutes>(time_since_midnight - hours);
auto seconds = std::chrono::floor<std::chrono::seconds>(time_since_midnight - minutes - hours);
std::ostringstream oss;
oss << hours.count() << ":" << std::setw(2) << std::setfill('0') << minutes.count() << ":" << seconds.count();
return oss.str();
}
int main() {
std::cout << time_of_day(std::chrono::system_clock::now());
}
Live Demo
It's not simple at all, and I'm sure there are corner cases I've neglected, but it works using only std::chrono facilities.
C++20 will introduce a couple of ways to do this more easily. At time of writing no standard library implementation has implemented either of them though.
First of all, if you want the full date/time, there will be an overloaded operator<<(std::ostream&, const std::chrono::system_clock::time_point&) that will format and print that for you:
int main() {
std::cout << std::chrono::system_clock::now();
}
If you want just the date or time part of the time_point, std::chrono::day_month_year, std::chrono::time_of_day, and friends can be used to decompose the time_point.
For instance, the above time_of_day function could be done much more simply like this:
std::chrono::time_of_day time_of_day(const std::chrono::sytem_clock::time_point& time_point)
{
auto midnight = std::chrono::floor<std::chrono::days>(time_point);
return std::chrono::time_of_day{time_point - midnight};
}
int main() {
std::cout << time_of_day(std::chrono::system_clock::now());
}
See P3055 for more info.
The other method is the new std::format family of functions. There will be a std::formatter specialization for std::chrono::system_clock::time_point that will let you format a time_point to a string using a strftime-like format string. For instance, the output of the following will be very similar (if not the same) as the previous two time_of_day functions:
int main() {
std::cout << std::format("{%T}", std::chrono::system_clock::now());
}
See P0645 and P1361 for more info.

auto t1 = system_clock::now(); is the fix
time_point is
template<
class Clock,
class Duration = typename Clock::duration
> class time_point;
and system_clock::to_time_t wants time_point<system_clock> type, but you provide completly different type time_point<high_resolution_clock>

read the Note under this link
Notes
The high_resolution_clock is not implemented consistently across different standard library implementations, and its use should be avoided. It is often just an alias for std::chrono::steady_clock or std::chrono::system_clock, but which one it is depends on the library or configuration. When it is a system_clock, it is not monotonic (e.g., the time can go backwards). For example, for gcc's libstdc++ it is system_clock, for MSVC it is steady_clock, and for clang's libc++ it depends on configuration.
Generally one should just use std::chrono::steady_clock or std::chrono::system_clock directly instead of std::chrono::high_resolution_clock: use steady_clock for duration measurements, and system_clock for wall-clock time.
int main()
{
using namespace std::chrono;
auto nowTime = std::chrono::system_clock::now();
auto tt = system_clock::to_time_t(nowTime);
std::cout << "Right now it is: " << ctime(&tt) << std::endl;
}

the best performance way is :
#include <stdint.h>
uint64_t get_time_us() {
struct timeval tv {0, 0};
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec; // microsecond
}
uint64_t t0 = get_time_us();
// do_something
uint64_t t1 = get_time_us();
int time_cost = t1 - t0;
and for C++11:
std::chrono::high_resolution_clock::time_point t1, t2
t1 = std::chrono::high_resolution_clock::now();
// do_something
t2 = std::chrono::high_resolution_clock::now();
int time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); // ms
// int time_us = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); // us
for boost:
#include <date_time/posix_time/posix_time.hpp>
boost::posix_time::ptime t1(boost::posix_time::microsec_clock::universal_time());
// do_something
boost::posix_time::ptime t2(boost::posix_time::microsec_clock::universal_time());
boost::posix_time::time_duration diff(t2 - t1);
int micro_sec = diff.total_microseconds();

Related

Converting time in milliseconds since epoch to time in yy-dd-hh-ss format

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();
}

How to measure elapsed time without being affected by changes in system time

I want to measure elapsed time in seconds. With std::chrono::steady_clock I do it. However it suffers from system time changes.
Wasn't steady_clock supposed to not being affected by changes in system time?
How can I do that?
Here is the code:
#include <iostream>
#include <chrono>
#include <time.h>
std::chrono::steady_clock::time_point t = std::chrono::steady_clock::now();
/* Change system time */
std::time_t tnow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
tnow -= 20;
std::cout << "stime: " << stime(&tnow) << std::endl;
/********************************************************/
sleep(5);
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;
This results:
stime: 0
ELAPSED: -15
What I wanted to get was:
ELAPSED: 5
Edit:
I have added C tag, because it seems that it is a kernel (or buildroot of board) bug. So, how could I achieve this without chrono? I mean, in a straight way (without having to watch system time changes).
How was the people living before chrono?
You can file a bug with your vendor.
From the standard:
Objects of class steady_­clock represent clocks for which values of
time_­point never decrease as physical time advances and for which
values of time_­point advance at a steady rate relative to real
time. That is, the clock may not be adjusted.
If you can find a reliable source of monotonic time on your system, you can easily wrap that source in a custom chrono::clock and subsequently still make use of the type-safe chrono system. For example:
#include <chrono>
struct MyClock
{
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<MyClock>;
static constexpr bool is_steady = true;
static time_point now() noexcept
{
using namespace std::chrono;
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return time_point{seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec}};
}
};
Now you can say things like:
MyClock::time_point t = MyClock::now();
// ...
MyClock::time_point t2 = MyClock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;

Getting current time with millisecond precision using put_time in C++

I am using the following code to get the current time in C++.
std::time_t t = std::time(nullptr);
std::time(&t);
std::cout << std::put_time(std::localtime(&t), "%X,");
However, this gives me time in HH::MM::SS. But for my application I also want to include time in milliseconds. Is there anyway to get something like HH::MM::SS::msecs using std::put_time?
Or what are the alternatives to get the system time with milliseconds precision inside a C++ program?
Here's one example using some C++11 <chrono> features. If you can use C++20, check out the new <chrono> features for more goodies or take a look at Howard Hinnants Date library.
#include <chrono>
#include <cstdint>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
// A C++11 constexpr function template for counting decimals needed for
// selected precision.
template<std::size_t V, std::size_t C = 0,
typename std::enable_if<(V < 10), int>::type = 0>
constexpr std::size_t log10ish() {
return C;
}
template<std::size_t V, std::size_t C = 0,
typename std::enable_if<(V >= 10), int>::type = 0>
constexpr std::size_t log10ish() {
return log10ish<V / 10, C + 1>();
}
// A class to support using different precisions, chrono clocks and formats
template<class Precision = std::chrono::seconds,
class Clock = std::chrono::system_clock>
class log_watch {
public:
// some convenience typedefs and "decimal_width" for sub second precisions
using precision_type = Precision;
using ratio_type = typename precision_type::period;
using clock_type = Clock;
static constexpr auto decimal_width = log10ish<ratio_type{}.den>();
static_assert(ratio_type{}.num <= ratio_type{}.den,
"Only second or sub second precision supported");
static_assert(ratio_type{}.num == 1, "Unsupported precision parameter");
// default format: "%Y-%m-%dT%H:%M:%S"
log_watch(const std::string& format = "%FT%T") : m_format(format) {}
template<class P, class C>
friend std::ostream& operator<<(std::ostream&, const log_watch<P, C>&);
private:
std::string m_format;
};
template<class Precision, class Clock>
std::ostream& operator<<(std::ostream& os, const log_watch<Precision, Clock>& lw) {
// get current system clock
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
os << std::put_time(std::localtime(&t), lw.m_format.c_str());
// only involve chrono duration calc for displaying sub second precisions
if(lw.decimal_width) { // if constexpr( ... in C++17
// 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 sub second part
os << std::setfill('0') << std::setw(lw.decimal_width) << ss.count();
}
return os;
}
int main() {
// default precision, clock and format
log_watch<> def_cp; // <= C++14
// log_watch def; // >= C++17
// alt. precision using alternative formats
log_watch<std::chrono::milliseconds> milli("%X,");
log_watch<std::chrono::microseconds> micro("%FT%T.");
// alt. precision and clock - only supported if the clock is an alias for
// system_clock
log_watch<std::chrono::nanoseconds,
std::chrono::high_resolution_clock> nano("%FT%T.");
std::cout << "def_cp: " << def_cp << "\n";
std::cout << "milli : " << milli << "\n";
std::cout << "micro : " << micro << "\n";
std::cout << "nano : " << nano << "\n";
}
Example output:
def_cp: 2019-11-21T13:44:07
milli : 13:44:07,871
micro : 2019-11-21T13:44:07.871939
nano : 2019-11-21T13:44:07.871986585
The accepted answer is a good one, but I would like to demonstrate doing this with an open-source, third-party, date handling library:
auto now = std::chrono::system_clock::now();
std::cout << date::format("%T", std::chrono::floor<std::chrono::milliseconds>(now));
This just output, for me: 10:01:46.654.
The fractional seconds separator is locale specific. In Sweden, where I reside, they use the comma as a separator. date::format allows supplying a std::locale, so we can force the use of the Swedish locale, for example, on my machine:
auto now = std::chrono::system_clock::now();
std::cout << date::format(std::locale("sv-SE"), "%T", std::chrono::floor<std::chrono::milliseconds>(now));
Now the ouput is: 10:02:32,169.
This formatting has been accepted in C++20, so you will get this when the vendors have implemented it :)
Of course, if the "%X" formatting is really want you want, then you cannot have decimal seconds and need to append them yourself:
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch() % std::chrono::seconds{1});
std::cout << date::format("%X", std::chrono::floor<std::chrono::milliseconds>(now)) << "," << ms.count();
Note that I am using ms.count() because in C++20 streaming a duration will append the units as well, meaning that << ms would output something like 123ms.

Add time duration to C++ timepoint

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;

Measuring time results in return values of 0 or 0.001

I am trying to use chrono::steady_clock to measure fractional seconds elapsed between a block of code in my program. I have this block of code working in LiveWorkSpace (http://liveworkspace.org/code/YT1I$9):
#include <chrono>
#include <iostream>
#include <vector>
int main()
{
auto start = std::chrono::steady_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = std::chrono::steady_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
std::cout << "seconds since start: " << ((double)difference / 1000000);
}
When I implement the same idea into my program like so:
auto start = std::chrono::steady_clock::now();
// block of code to time
auto end = std::chrono::stead_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
std::cout << "seconds since start: " << ((double) difference / 1000000);
The program will only print out values of 0 and 0.001. I highly doubt that the execution time for my block of code always equals 0 or 1000 microseconds, so what is accounting for this rounding and how might I eliminate it so that I can get the proper fractional values?
This is a Windows program.
This question already has a good answer. But I'd like to add another suggestion:
Work within the <chrono> framework. Build your own clock. Build your own time_point. Build your own duration. The <chrono> framework is very customizable. By working within that system, you will not only learn std::chrono, but when your vendor starts shipping clocks you're happy with, it will be trivial to transition your code from your hand-rolled chrono::clock to std::high_resolution_clock (or whatever).
First though, a minor criticism about your original code:
std::cout << "seconds since start: " << ((double) difference / 1000000);
Whenever you see yourself introducing conversion constants (like 1000000) to get what you want, you're not using chrono correctly. Your code isn't incorrect, just fragile. Are you sure you got the right number of zeros in that constant?!
Even in this simple example you should say to yourself:
I want to see output in terms of seconds represented by a double.
And then you should use chrono do that for you. It is very easy once you learn how:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
The first line creates a type with a period of 1 second, represented by a double.
The second line simply subtracts your time_points and assigns it to your custom duration type. The conversion from the units of steady_clock::time_point to your custom duration (a double second) are done by the chrono library automatically. This is much simpler than:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
And then finally you just print out your result with the .count() member function. This is again much simpler than:
std::cout << "seconds since start: " << ((double) difference / 1000000);
But since you're not happy with the precision of std::chrono::steady_clock, and you have access to QueryPerformanceCounter, you can do better. You can build your own clock on top of QueryPerformanceCounter.
<disclaimer>
I don't have a Windows system to test the following code on.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Since you wanted your output in terms of a double second, I've made the rep of this clock a double and the period 1 second. You could just as easily make the rep integral and the period some other unit such as microseconds or nanoseconds. You just adjust the typedefs and the conversion from QueryPerformanceCounter to your duration in now().
And now your code can look much like your original code:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
But without the hand-coded conversion constants, and with (what I'm hoping is) sufficient precision for your needs. And with a much easier porting path to a future std::chrono::steady_clock implementation.
<chrono> was designed to be an extensible library. Please extend it. :-)
After running some tests on MSVC2012, I could confirm that the C++11 clocks in Microsoft's implementation do not have a high enough resolution. See C++ header's high_resolution_clock does not have high resolution for a bug report concerning this issue.
So, unfortunately for a higher resolution timer, you will need to use boost::chrono or QueryPerformanceCounter directly like so until they fix the bug:
#include <iostream>
#include <Windows.h>
int main()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER start;
QueryPerformanceCounter(&start);
// Put code here to time
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
// for microseconds use 1000000.0
double interval = static_cast<double>(end.QuadPart- start.QuadPart) /
frequency.QuadPart; // in seconds
std::cout << interval;
}