ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.82k stars 2.55k forks source link

time.nanoTimestamp epoch should not have leap seconds (propose GPS time or TAI) #8781

Open PhaseMage opened 3 years ago

PhaseMage commented 3 years ago

UTC has leap seconds, which are a pain to deal with in a few corner cases. This results in an ambiguous description of time.nanoTimestamp. Right now, it's hard for two separate services written in Zig to share timestamps without also having to share how many leap seconds were included in the timestamp (there's also no std library API to determine how many leap seconds are included in a timestamp, so even that is hard).

Proposal:

  1. The Zig std library time API standardize on a consistent epoch with no ambiguities, such as GPS time or TAI. By choosing a more consistent epoch, the API will continue to work consistently even with an executable that was compiled prior to a leap second being declared, but executed AFTER the leap second occurs.
  2. For formatting of timestamps to a user-readable format, there would need to be a Zig std library API for converting nanoTimestamps to year/month/day/hour/min/sec/ns. This API would need to defer to the OS in order to take leap second updates into account (see mktime() on Linux or FileTimeToSystemTime() on Windows), since only the OS would be expected to get dynamic leap second updates as future ones are declared and be able to correctly handle them.

Windows now correctly supports leap seconds (as of October 2018 update). FILETIME is always in the NTFS/Windows Epoch, which does not jump around with leap seconds.

On Linux, CLOCK_REALTIME tries to follow UTC, which jumps around with leap seconds. CLOCK_TAI is supported since Linux 3.10, and follows International Atomic Time (no leap seconds).

daurnimator commented 3 years ago

I think people would expect the "main" time to match UTC.

For measuring time intervals, people should use CLOCK_MONOTONIC anyway.


I don't think unixy platforms aside from linux support TAI; e.g. AFAIK, no BSD has implemented CLOCK_TAI.

PhaseMage commented 3 years ago

My main concern is having a timestamp with a clear definition across platforms.

Personally, I need timestamps that can be used in distributed systems. CLOCK_MONOTONIC is not useful in that scenario.

Right now, time.nanoTimestamp() has divergent behavior across Windows and non-Windows platforms. On Windows, it uses an epoch without leap seconds to naively convert to an epoch with leap seconds (UTC). epoch.windows will need to change after each leap second, but it's a compile-time constant. On Linux, CLOCK_REALTIME has jumps due to leap seconds that nobody ever remembers are possible, and are the source of many computer outages every time they occur.

PhaseMage commented 3 years ago

Yes, people would 'expect' the "main" time to be UTC, but they also don't expect UTC to have leap seconds. People's expectations of UTC are flawed. This is a well-documented source of critical bugs.

As Wikipedia points out: "The most obvious workaround is to use the TAI scale for all operational purposes and convert to UTC for human-readable text. UTC can always be derived from TAI with a suitable table of leap seconds; the reverse is unsure."

Require an OS or Network request (which understands leap seconds) to do any sort of 'unpacking' into year/month/day/hour/min/sec/ns.