add tai64 module to anoia

This commit is contained in:
Daniel Barlow
2025-10-06 22:02:55 +01:00
parent a343e63231
commit 59eea64985
2 changed files with 80 additions and 2 deletions

View File

@@ -1,9 +1,9 @@
servicedir:=$(shell mktemp -d)
outputdir:=$(servicedir)/.outputs
default: fs.lua init.lua nl.lua svc.lua process.lua net/constants.lua
default: fs.lua init.lua nl.lua svc.lua process.lua net/constants.lua tai64.lua
CHECK=fs.fnl init.fnl svc.fnl process.fnl
CHECK=fs.fnl init.fnl svc.fnl process.fnl tai64.fnl
check:
ln -s . anoia

78
pkgs/anoia/tai64.fnl Normal file
View File

@@ -0,0 +1,78 @@
(local { : base64 : assoc } (require :anoia))
(import-macros { : expect= : define-tests } :anoia.assert)
(local
leap-seconds-list
(let [tbl
[
;; https://data.iana.org/time-zones/data/leap-seconds.list
;; comments are the _start_ of the day where the second was
;; added at the end of the previous day
[2272060800 10] ; 1 jan 1972 ; baseline, not a leap second
[2287785600 11] ; 1 jul 1972
[2303683200 12] ; 1 jan 1973
[2335219200 13] ; 1 jan 1974
[2366755200 14] ; 1 Jan 1975
[2398291200 15] ; 1 Jan 1976
[2429913600 16] ; 1 Jan 1977
[2461449600 17] ; 1 Jan 1978
[2492985600 18] ; 1 Jan 1979
[2524521600 19] ; 1 Jan 1980
[2571782400 20] ; 1 Jul 1981
[2603318400 21] ; 1 Jul 1982
[2634854400 22] ; 1 Jul 1983
[2698012800 23] ; 1 Jul 1985
[2776982400 24] ; 1 Jan 1988
[2840140800 25] ; 1 Jan 1990
[2871676800 26] ; 1 Jan 1991
[2918937600 27] ; 1 Jul 1992
[2950473600 28] ; 1 Jul 1993
[2982009600 29] ; 1 Jul 1994
[3029443200 30] ; 1 Jan 1996
[3076704000 31] ; 1 Jul 1997
[3124137600 32] ; 1 Jan 1999
[3345062400 33] ; 1 Jan 2006
[3439756800 34] ; 1 Jan 2009
[3550089600 35] ; 1 Jul 2012
[3644697600 36] ; 1 Jul 2015
[3692217600 37] ; 1 Jan 2017
]]
(icollect [_ [ts dtai] (ipairs tbl)]
[(+ (- ts 2208988800) dtai) dtai])))
(fn leap-seconds [timestamp]
(accumulate [secs 10
_ [epoch leap-seconds] (ipairs leap-seconds-list)
&until (> epoch timestamp)]
leap-seconds))
(define-tests :leap-seconds
(expect= (leap-seconds 104694412) 12)
(expect= (leap-seconds 23) 10)
(expect= (leap-seconds (+ 3692217600 60)) 37)
(expect= (leap-seconds (+ 10 773020829)) 29)
(expect= (leap-seconds 362793520) 19))
(fn from-timestamp [str]
(if (= (string.sub str 1 1) "@")
(let [s (tonumber (string.sub str 2 17) 16)
two_62 (lshift 1 62)
sec (if (>= s two_62)
(- s two_62)
(- two_62 s))
nano (tonumber (string.sub str 18 25) 16)]
{:s sec :n nano})
nil))
(fn to-utc [tai]
(+ (- tai.s (leap-seconds tai.s)) (/ tai.n 1e9)))
(define-tests
(expect=
(from-timestamp "@4000000068e2f0d3257dc09b")
{:s 1759703251 :n 628998299})
(expect= (to-utc (from-timestamp "@4000000068e2f0d3257dc09b"))
1759703214.628998299))
{ : from-timestamp : to-utc }