The minimum representable duration is high_resolution_clock::period::num / high_resolution_clock::period::den
seconds. You can print it like this:
std::cout << (double) std::chrono::high_resolution_clock::period::num
/ std::chrono::high_resolution_clock::period::den;
Why is this? A clock's ::period
member is defined as "The tick period of the clock in seconds." It is a specialization of std::ratio
which is a template to represent ratios at compile-time. It provides two integral constants: num
and den
, the numerator and denominator of a fraction, respectively.
(In this post I will omit std::chrono::
qualifications for clarity. I trust you know where they go.)
The reason your code example fails to compile is that there is a mismatch between the return type of system_clock::now()
and the type of variable you are trying to assign this to (time_point<system_clock, nanoseconds>
).
The documented return value of system_clock::now()
is system_clock::time_point
, which is a typedef for time_point<system_clock, system_clock::duration>
. system_clock::duration
is implementation-defined, with microseconds
and nanoseconds
being commonly used. It seems that your implementation uses microseconds
, so the return type of system_clock::now()
is time_point<system_clock, microseconds>
.
time_point
s with different durations are not implicitly convertible to one another, so you get a compiler error.
You can explicitly convert time points with different durations using time_point_cast
, so the following would compile on your system:
time_point<system_clock, nanoseconds> time_point;
time_point = time_point_cast<nanoseconds>(system_clock::now());
Notice the explicit template parameter to time_point_cast
is the target duration type, not the target time_point type. The clock types must match in a time_point_cast
, so specifying the entire time_point type (which is templated on both the clock type and the duration type) would be redundant.
Of course in your case, since you are just looking to print the time point, there is no need for it to be at any specific resolution, so you can just declare time_point
to be the same type as what system_clock::now()
returns to begin with. A simple way to do that is to use the system_clock::time_point
typedef:
system_clock::time_point time_point;
time_point = system_clock::now(); // no time_point_cast needed
Since this is C++11, you can also just use auto
:
auto time_point = system_clock::now();
Having solved this compiler error, the conversion to time_t
works just fine:
std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);
and you can now use standard methods for displaying time_t
values, like std::ctime
or std::strftime
. (As Cassio Neri points out in a comment to your question, the more C++-y std::put_time
function is not yet supported by GCC).
Best Answer
There is no truly graceful way to do this.
high_resolution_clock
is not known to be related to UTC, or any other calendar. One thing you can portably do is output its current duration from its unspecified epoch, along with the units of that duration:Which for me outputs:
which means it is 516583779589531 nanoseconds (or 516,583.779589531 seconds) since the epoch of this clock on my machine. On my machine this translates to: my machine has been booted up for nearly 6 days. But that translation is not portable.
Ah! And I note from your error message that you are using libc++. If you are also on OS X, then we have the same definition of
high_resolution_clock
: It counts nanoseconds since your computer was booted.