]> Cypherpunks.ru repositories - gotai64n.git/blob - tai64n.go
34a63d185c2c1e351d1920394ed6bca71c7667b4
[gotai64n.git] / tai64n.go
1 /*
2 go.cypherpunks.ru/tai64n -- Pure Go TAI64N implementation
3 Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package tai64n
19
20 import (
21         "encoding/binary"
22         "encoding/hex"
23         "errors"
24         "strings"
25         "time"
26 )
27
28 const (
29         Size     = 12
30         Base     = 0x400000000000000a
31         LocalFmt = "2006-01-02 15:04:05.000000000"
32 )
33
34 type TAI64N [Size]byte
35
36 func FromTime(t time.Time, tai *TAI64N) {
37         binary.BigEndian.PutUint64(tai[:], uint64(Base)+uint64(t.Unix()))
38         binary.BigEndian.PutUint32(tai[8:], uint32(t.Nanosecond()))
39 }
40
41 func ToTime(tai []byte) time.Time {
42         if len(tai) != Size {
43                 panic("invalid size")
44         }
45         secs := int64(binary.BigEndian.Uint64(tai[:8]))
46         nano := int64(binary.BigEndian.Uint32(tai[8:]))
47         return time.Unix(secs-Base, nano)
48 }
49
50 func (tai TAI64N) Encode() string {
51         return "@" + hex.EncodeToString(tai[:])
52 }
53
54 func Decode(s string) (time.Time, error) {
55         tai, err := hex.DecodeString(strings.TrimPrefix(s, "@"))
56         if len(tai) != Size {
57                 return time.Time{}, errors.New("invalid ts length")
58         }
59         if err != nil {
60                 return time.Time{}, err
61         }
62         return ToTime(tai), nil
63 }