X-Git-Url: http://www.git.cypherpunks.ru/?p=gotai64n.git;a=blobdiff_plain;f=leapsecs.go;fp=leapsecs.go;h=fe80b8ac55196d41e1ce7bb057028212d0fad200;hp=0000000000000000000000000000000000000000;hb=9978840e570dfe3a23e2db36d64237febceaebcf;hpb=266a0ae363ebb2c96e0a1d700c20bfc3a3188788 diff --git a/leapsecs.go b/leapsecs.go new file mode 100644 index 0000000..fe80b8a --- /dev/null +++ b/leapsecs.go @@ -0,0 +1,67 @@ +/* +go.cypherpunks.ru/tai64n -- Pure Go TAI64/TAI64N implementation +Copyright (C) 2020-2021 Sergey Matveev + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package tai64n + +import ( + "sort" + "time" +) + +const Leapsecs1972 = 10 + +// Database of Unix timestamps of the time when leap second occurred. +// Library contains and initializes it with leap seconds up to 2016-12-31. +var LeapsecsDB []int64 + +// TAI<->UTC difference for the given Unix timestamp. +func LeapsecsDiff(t int64) int { + for i, leap := range LeapsecsDB { + if t > leap { + return len(LeapsecsDB) - i + } + } + return 0 +} + +// Add currently known (LeapsecsDB) leap seconds, not including initial +// 1972-01-01 10-seconds offset. +func LeapsecsAdd(t time.Time) time.Time { + return t.Add(time.Second * time.Duration(LeapsecsDiff(t.Unix()))) +} + +// Opposite of LeapsecsAdd(). +func LeapsecsSub(t time.Time) time.Time { + return t.Add(-time.Second * time.Duration(LeapsecsDiff(t.Unix()))) +} + +type Int64s []int64 + +func (a Int64s) Len() int { return len(a) } +func (a Int64s) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a Int64s) Less(i, j int) bool { return a[i] > a[j] } + +// Load "leapsecs.dat"-like database: concatenated TAI64 leap seconds. +// Function panics if encoding is invalid. +func LeapsecsDBLoad(buf []byte) { + db := make([]int64, 0, len(buf)/TAI64Size) + for i := 0; i < len(buf); i += TAI64Size { + db = append(db, (ToTime(buf[i:i+TAI64Size]).Unix()/86400)*86400) + } + sort.Sort(Int64s(db)) + LeapsecsDB = db +}