'How to create a time point from milliseconds since Unix epoch?

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?



Solution 1:[1]

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_points 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_points and durations 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_points, 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);

Solution 2:[2]

auto ms_since_epoch(std::int64_t m){
  return std::chrono::system_clock::from_time_t(time_t{0})+std::chrono::milliseconds(m);
}

this returns a system clock time point.

Like most things calendar/time related, the odds this covers things like leap seconds properly is low; odds are your ms since unix epoch value might be off by them, for example.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Yakk - Adam Nevraumont