From 4aa3fe62a67788000896fc2b7f17f1078192bbe7 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 10 Dec 2020 16:42:45 +0300 Subject: [PATCH] Initial commit --- go.mod | 3 +++ tai64n.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 go.mod create mode 100644 tai64n.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..79a8308 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go.cypherpunks.ru/tai64n + +go 1.14 diff --git a/tai64n.go b/tai64n.go new file mode 100644 index 0000000..34a63d1 --- /dev/null +++ b/tai64n.go @@ -0,0 +1,63 @@ +/* +go.cypherpunks.ru/tai64n -- Pure Go TAI64N implementation +Copyright (C) 2020 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 ( + "encoding/binary" + "encoding/hex" + "errors" + "strings" + "time" +) + +const ( + Size = 12 + Base = 0x400000000000000a + LocalFmt = "2006-01-02 15:04:05.000000000" +) + +type TAI64N [Size]byte + +func FromTime(t time.Time, tai *TAI64N) { + binary.BigEndian.PutUint64(tai[:], uint64(Base)+uint64(t.Unix())) + binary.BigEndian.PutUint32(tai[8:], uint32(t.Nanosecond())) +} + +func ToTime(tai []byte) time.Time { + if len(tai) != Size { + panic("invalid size") + } + secs := int64(binary.BigEndian.Uint64(tai[:8])) + nano := int64(binary.BigEndian.Uint32(tai[8:])) + return time.Unix(secs-Base, nano) +} + +func (tai TAI64N) Encode() string { + return "@" + hex.EncodeToString(tai[:]) +} + +func Decode(s string) (time.Time, error) { + tai, err := hex.DecodeString(strings.TrimPrefix(s, "@")) + if len(tai) != Size { + return time.Time{}, errors.New("invalid ts length") + } + if err != nil { + return time.Time{}, err + } + return ToTime(tai), nil +} -- 2.44.0