79 lines
2.8 KiB
Fennel
79 lines
2.8 KiB
Fennel
(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 }
|