[PATCH] libc/time: Add CLOCK_TAI

brian.inglis@systematicsw.ab.ca brian.inglis@systematicsw.ab.ca
Tue Jul 15 21:01:52 GMT 2025


On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
> On Jul 14 14:38, Brian Inglis via Newlib wrote:
>> On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
>>> On Jul 11 06:35, Sebastian Huber wrote:
>>>> FreeBSD also provides this clock identifier, maybe it should be
>>>> #if __BSD_VISIBLE
>>>> #define CLOCK_TAI		(11)
>>>> #endif
>>>> ?
>>
>>> Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
>>
>>> IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
>>> return the same value, because the leap second is set to 0 at kernel
>>> startup.  Maybe that's enough...
>>
>> If you are running an NTP server you just have to ask for the system variable:
>>
>> $ ntpq -c'rv 0 tai'
>> tai=37
>> $ ntpq -c'rv 0 tai,leapsec,expire'
>> tai=37, leapsec=201701010000, expire=202606280000
>>
>> assuming you keep it updated from IERS, NIST, and/or USNO upstreams.
>>
>> Or install tzdata-right to get leapsecond compensated timezones at TAI-10s:
>>
>> $ ntptime.sh; TZ=right/UTC date +%c%z; date -u +%c%z; TZ=right/$TZ date
>> +%c%z; date +%c%z
>> 2025 Jul 14 Mon 20:15:33+0000  JD 2460871.344132  MJD 60870.844132  ToD 72933
>> NTP 3961512933  Unix 1752524133  TAI-UTC 37  TAI-GPS 19  GPS-UTC 18
>> GPS We 2375  Cy 2 Wn 327  Wa 71  ToW 159351  DoW 1 ToD 72951
>> 2025 Jul 14 Mon 20:15:06+0000
>> 2025 Jul 14 Mon 20:15:33+0000
>> 2025 Jul 14 Mon 14:15:06-0600
>> 2025 Jul 14 Mon 14:15:33-0600
>>
>> These are updated with every IERS Bulletin C leapsecond announcement and
>> data update, made available in the next tzdata release.
> 
> I read up on leap secs and TAI yesterday, and it seems Linux is not doing
> as lot by itself (i.e., the kernel).  Also, leap secs are pretty static,
> especially since 2017. We had no leap sec since that time anymore, so we're
> on a 37 sec shift for ~8 years.
> 
> We need some way to handle that without extra packages.  Ideally this is
> between the Cygwin DLL and the OS with no extra layer between them.
> Unfortunately I didn't find a Windows API to ask the OS for the current
> leap secs offset.
> 
> What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
> for the time being, and the DLL could check if a file "/etc/leapsecs"
> exists and read it to compensate for new leap secs.  We can add such a
> file to the distro when a new leap sec has been defined.

It may be better to just use the standard approach and standard file name which 
is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may itself be 
symlinked from /var/lib/ntp/.

Fedora chrony (RH default ntp implementation alternative) relies on Fedora 
tzdata to provide it, as the IERS upstream is included in the sources, and it is 
installed in /usr/share/zoneinfo, with the tzdata processed format leapseconds.

	https://src.fedoraproject.org/rpms/chrony/blob/main/f/chrony.spec
	https://src.fedoraproject.org/rpms/tzdata/blob/main/f/tzdata.spec
	https://src.fedoraproject.org/rpms/ntpsec/blob/main/f/ntpsec.spec

I could do the same in Cygwin tzdata, installing symlink(s) as above, leading 
back to /etc/leap-seconds.list, via any intermediates deemed necessary.

The dev tzdata sources are available from:

	https://github.com/eggert/tz

	https://github.com/eggert/tz/blob/main/leap-seconds.list

and the last non-comment line contains the current TAI offset and effective date 
as the NTP time stamp (NTP epoch is 1900-01-01 00:00:00Z so that offset from 
UNIX epoch can be added to convert):

	$ grep '^[^#]' /etc/leap-seconds.list | tail -1
	3692217600      37      # 1 Jan 2017
	$ date -u -d'1900-01-01 00:00:00+0000' +%s
	-2208988800
	$ date -u -d'1900-01-01 00:00:00+0000 + 3692217600 seconds'
	2017 Jan 01 Sun 00:00:00
> So, yeah, we can just add CLOCK_TAI and we add that functionality to
> the Cygwin DLL for the 3.7 release cycle. Shouldn't be too much work.
> 
> So, Sebastian, just go ahead defining CLOCK_TAI.  A __BSD_VISIBLE
> guard seems like a good idea.  Maybe adding a `|| _GNU_VISIBLE' for
> readability, even if that's redundant...
I run [Meinberg] ntpd/ntpq not w32tm, but another system shows:

 > w32tm /query /status /verbose
Leap Indicator: 0(no warning)
Stratum: 2 (secondary reference - syncd by (S)NTP)
Precision: -23 (119.209ns per tick)
Root Delay: 0.0561072s
Root Dispersion: 7.7939052s
ReferenceId: 0xD8C5E4E6 (source IP:  216.197.228.230)
Last Successful Sync Time: 2025-07-15 7:31:24 AM
Source: 0.ca.pool.ntp.org
Poll Interval: 15 (32768s)

Phase Offset: -0.0022481s
ClockRate: 0.0156250s
State Machine: 2 (Sync)
Time Source Flags: 0 (None)
Server Role: 576 (Reliable Time Service)
Last Sync Error: 2 (The computer did not resync because only stale time data was 
available.)

Time since Last Good Sync Time: 19676.7457267s

 > w32tm /leapseconds /getstatus /verbose

[Leap Seconds]
Enabled: 1 (Local)
Number of Leap Seconds (after June 2018): 0 (Local)
Leap Seconds List (Local):

https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings

https://techcommunity.microsoft.com/blog/networkingblog/top-10-networking-features-in-windows-server-2019-10-accurate-network-time/339739

https://techcommunity.microsoft.com/blog/networkingblog/leap-seconds-for-the-it-pro-what-you-need-to-know/339811

and w32tm updates allow leapseconds to be added and removed:

	https://github.com/microsoft/STL/discussions/1624

Updates may be visible at:

	https://microsoft.visualstudio.com/OS/_workitems/edit/32341669

 > w32tm /leapseconds /add:+2021-11-30T23:59:59 /force
The command completed successfully.

 > w32tm /leapseconds /getstatus /verbose
[Leap Seconds]
Enabled: 1 (Local)
Number of Leap Seconds (after June 2018): 1 (Local)
Leap Seconds List (Local):
+2021-11-30T23:59:59

 > w32tm /leapseconds /remove:+2021-11-30T23:59:59 /force
The command completed successfully.

My ntp server shows:

w32tm /stripchart /computer:localhost /dataonly /samples:10
Tracking localhost [[::1]:123].
Collecting 10 samples.
The current time is 2025-07-15 14:40:20.
14:40:20, -00.0000115s
14:40:22, +00.0001352s
14:40:24, +00.0001355s
14:40:26, +00.0001052s
14:40:28, +00.0000881s
14:40:30, +00.0000685s
14:40:32, +00.0000758s
14:40:34, +00.0000872s
14:40:36, +00.0000662s
14:40:38, +00.0000380s

 > w32tm /stripchart /computer:localhost /dataonly /samples:10 /rdtsc
Tracking localhost [[::1]:123].
Collecting 10 samples.
The current time is 2025-07-15 14:39:58.
RdtscStart, RdtscEnd, FileTime, RoundtripDelay, NtpOffset
2170263874159491, 2170263877515570, 133970855987299848, +00.0005957, +00.0000436
2170270901868499, 2170270904970262, 133970856007416482, +00.0003988, +00.0001364
2170277901548544, 2170277905644173, 133970856027452949, +00.0004523, +00.0001429
2170284903885522, 2170284907988833, 133970856047496959, +00.0006049, +00.0001642
2170291958659606, 2170291962514063, 133970856067691066, +00.0005711, +00.0000280
2170298960387316, 2170298964954578, 133970856087733330, +00.0007743, +00.0000636
2170305962010214, 2170305965895147, 133970856107775354, +00.0003717, +00.0001210
2170312965127357, 2170312969730343, 133970856127821599, +00.0007545, +00.0000768
2170319970032844, 2170319973530838, 133970856147872961, +00.0004328, +00.0001321
2170326974367562, 2170326978138033, 133970856167922687, +00.0004454, +00.0001380

-- 
Take care. Thanks, Brian Inglis              Calgary, Alberta, Canada

La perfection est atteinte                   Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter  not when there is no more to add
mais lorsqu'il n'y a plus rien à retrancher  but when there is no more to cut
                                 -- Antoine de Saint-Exupéry


More information about the Newlib mailing list