Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get POSIX epoch as system_clock::time_point

I'm aware that the default value of a std::chrono::system_clock::time_point is the clock's epoch, but I can't find any mandate in the C++11 standard that system_clock's epoch is the same as the POSIX epoch (1970-01-01T00:00:00Z). Is it safe to assume on Linux and Windows that this is the case? Or would it be smarter to use std::chrono::system_clock::from_time_t(0)?

like image 643
Matt Kline Avatar asked Dec 08 '14 19:12

Matt Kline


1 Answers

The standard leaves the epoch of std::chrono::system_clock::time_point unspecified.

There are three implementations of std::chrono::system_clock::time_point I am aware of:

  1. libc++
  2. libstdc++
  3. VS

All three of these are thin wrappers around Unix Time, which counts the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970,not counting leap seconds.

All of them are based on a signed 64 bit integral type. None of them are steady. libc++ has a tick period of microseconds. libstdc++ has a tick period of nanoseconds, and VS has a tick period of 0.1 microseconds.

In case it is useful, here is a paper which demonstrates some formula to take advantage of the unspecified but common epoch to convert back and forth from the civil calendar without going through time_t.

The advantage of using std::chrono::system_clock::from_time_t is that it is guaranteed to work by the standard. The disadvantage is that in practice it will limit you to the precision of a second (though that precision is unspecified).

The advantage of assuming the epoch of std::chrono::system_clock to be 1970-01-01, even though it is unspecified, is that you will be correct on all known implementations, and the precision available for this alternative is much higher than that provided by time_t.


Update

The draft C++2a spec now specifies system_clock to model Unix Time:

26.7.1.1 Overview [time.clock.system.overview]

1 Objects of type system_clock represent wall clock time from the system-wide realtime clock. Objects of type sys_time<Duration> measure time since (and before) 1970-01-01 00:00:00 UTC excluding leap seconds. This measure is commonly referred to as Unix time. This measure facilitates an efficient mapping between sys_time and calendar types (26.8). [Example: sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s. sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946’684’800s, which is 10’957 * 86’400s. —end example]

And the synopsis ([time.syn]) has previously defined:

template<class Duration>
  using sys_time  = time_point<system_clock, Duration>;
using sys_seconds = sys_time<seconds>;
using sys_days    = sys_time<days>;

We are hopeful that the "a" in "C++2a" will be "0".

like image 98
Howard Hinnant Avatar answered Oct 17 '22 01:10

Howard Hinnant