To create a time point for the current time, you can use: std::chrono::system_clock::now()
.
I cannot figure out, however, how to create a time point given milliseconds since the UNIX epoch?
Also, is std::chrono::time_point
even the recommended way to represent "instants" in time? Or should std::time_t
be preferred?
This is easier/simpler:
std::chrono::system_clock::time_point tp{std::chrono::milliseconds{m}};
The above has a precision of system_clock::precision
(microseconds
on macOS, nanoseconds
on Linux systems, and 1/10 microseconds
on Windows). You could also create a time_point
with a precision of milliseconds
if desired:
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
tp{std::chrono::milliseconds{m}};
In C++20 this can be simplified to:
std::chrono::sys_time tp{std::chrono::milliseconds{m}};
sys_time
is just a template type alias for the system_clock
family of time_point
s at any precision. I.e. the above is the exact same type as the milliseconds
precision time_point
created before.
Also, is std::chrono::time_point even the recommended way to represent "instants" in time? Or should std::time_t be preferred?
I recommend std::chrono::system_clock::time_point
over std::time_t
:
time_point
's based on system_clock
have a well-defined epoch (in C++20) which is also a de-facto standard in C++17: It counts time since 1970-01-01 00::00:00 UTC, excluding leap seconds. This is also known as Unix Time. In contrast no C or C++ standard specifies the epoch of time_t
, though using Unix Time is common practice, and specified by POSIX.
Though unspecified, time_t
typically has a precision of seconds
. system_clock::time_point
typically has a precision that is millions or billions finer than that. The exact precision is not specified, but it is documented within the API so you can discover it at compile-time or run-time. system_clock::period
is the same std::ratio
as system_clock::time_point::period
and represents a compile-time fraction of a second from one tick to the next.
time_t
is typically just a 32 or 64 bit signed integral. This has no type safety in generic code. For example you can add two time_t
's and it compiles. However adding two points in time is not logical (while subtracting them is). The chrono library catches such logic bugs at compile-time. Adding two time_point
's does not compile. But you can add a time_point
and any duration
. The logical algebra of time_point
s and duration
s is checked for you at compile-time.
If you need to cover leap seconds, it is unspecified but common that time_t
does not (typically it is Unix Time). With system_clock
, Unix Time is specified (you know you aren't counting leap seconds). However in C++20 there is another chrono clock that does include leap seconds in its count: std::chrono::utc_clock
. Like all chrono clocks this clock has it's own type-safe family of time_point
s, with its own convenience template type alias called utc_time<Duration>
. And you can convert between them using std::chrono::clock_cast
.
like this:
auto tp_sys = clock_cast<system_clock>(tp_utc);