/* go.cypherpunks.ru/tai64n -- Pure Go 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 ( "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(src time.Time, dst *TAI64N) { binary.BigEndian.PutUint64(dst[:], uint64(Base)+uint64(src.Unix())) binary.BigEndian.PutUint32(dst[8:], uint32(src.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 }