user877329
user877329

Reputation: 6200

Leap seconds and std::chrono

I took a look att cppreference.org (emphasis mine):

The clock std::chrono::utc_clock is a Clock that represents Coordinated Universal Time (UTC). It measures time since 00:00:00 UTC, Thursday, 1 January 1970, including leap seconds.

Comparing that to the definition of system_clock:

system_clock measures Unix Time (i.e., time since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, not counting leap seconds).

Is it actually possible to have both in the same system? For example, if the system clock is synchronized via NTP, then the server decides what time it is, and that could use leap seconds or not, but the C++ library implementation cannot know anything about that. Or, does the standard require a database over when a leap second was introduced?

Upvotes: 3

Views: 3579

Answers (2)

Gerard Ashton
Gerard Ashton

Reputation: 638

I found this working draft about time for C++ 20, which seems to be due out in AD 2020. It has a subpage about utc_clock which includes this example:

clock_­cast<utc_­clock>(sys_­seconds{sys_­days{1970y/January/1}}).time_­since_­epoch() is 0s.
clock_­cast<utc_­clock>(sys_­seconds{sys_­days{2000y/January/1}}).time_­since_­epoch()

and states the last value "is 946'684'822s, which is 10'957 * 86'400s + 22s." Notice that 10,957 days are about 30 years, so the value of utc_clock evidently represents seconds since 1 January 1970 UTC, where each leap second increments the value of utc_clock.

Since this is expressed as a conversion, it seems reasonable to infer the conversion would call upon a table of leap seconds, and could be performed even if the operating system had no notion of the distinction between UTC and TAI, and no concept of a minute which contained 61 seconds.

I must admit I am more interested in time than C++ and have not written serious C++ code in nearly 20 years.

Upvotes: 2

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385108

NTP servers give you UTC (in a seconds-since-1900 format). The current time, is the current time. It doesn't really matter how many leap seconds there have been in order to get there.

Where things get complicated is when a leap second is added. NTP will announce this in the moment, and various operating systems do various things internally to record that, owing to their propensity to store time as "number of seconds since an epoch" — Linux and Windows don't include leap seconds in this, because it would make their timestamp rendering more complicated (how many leap seconds have there been?) and they can't be dealing with. Instead, they just slow or speed up the clock for a little while around the announced leap second, so rather than actually recording it they just adjust their own seconds-count so rendering that count as a timestamp will appear accurate later.

(What I don't know is how an OS will redetermine its not-really-but-sort-of-seconds count from an NTP transaction without knowing how many leap seconds to deduct; edits welcomed.)

system_clock gives you this seconds count, which (on mainstream platforms) just comes straight from the OS (e.g. time()).

utc_clock gives you a similar seconds count, but one that is "real". On such mainstream platforms this will necessarily have to be the system_clock with leap seconds added after-the-fact. This historical data comes from the system too, indeed some kind of database (though the exact source is up to the implementation).

In conclusion, the data sources for the two clocks are (slightly) different, so there is no question of whether they can co-exist on the same system. But, the system_clock probably comes directly from your operating system, in a way that the utc_clock probably doesn't.

Further reading

Upvotes: 3

Related Questions