From 1cfbf114ecad8565e91d84c65689cd0a4e78c027 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Oct 2023 14:25:33 +0300 Subject: [PATCH] Add jsontime nanosecond and string helpers --- jsontime/helpers.go | 59 +++++++++++++++++ jsontime/{jsontime.go => integer.go} | 87 +++++++++---------------- jsontime/string.go | 95 ++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 58 deletions(-) create mode 100644 jsontime/helpers.go rename jsontime/{jsontime.go => integer.go} (53%) create mode 100644 jsontime/string.go diff --git a/jsontime/helpers.go b/jsontime/helpers.go new file mode 100644 index 0000000..35f4cc2 --- /dev/null +++ b/jsontime/helpers.go @@ -0,0 +1,59 @@ +// Copyright (c) 2023 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package jsontime + +import ( + "time" +) + +func UM(time time.Time) UnixMilli { + return UnixMilli{Time: time} +} + +func UMInt(ts int64) UnixMilli { + return UM(time.UnixMilli(ts)) +} + +func UnixMilliNow() UnixMilli { + return UM(time.Now()) +} + +func UMicro(time time.Time) UnixMicro { + return UnixMicro{Time: time} +} + +func UMicroInto(ts int64) UnixMicro { + return UMicro(time.UnixMicro(ts)) +} + +func UnixMicroNow() UnixMicro { + return UMicro(time.Now()) +} + +func UN(time time.Time) UnixNano { + return UnixNano{Time: time} +} + +func UNInt(ts int64) UnixNano { + return UN(time.Unix(0, ts)) +} + +func UnixNanoNow() UnixNano { + return UN(time.Now()) +} + +func U(time time.Time) Unix { + return Unix{Time: time} +} + +func UInt(ts int64) Unix { + return U(time.Unix(ts, 0)) +} + +func UnixNow() Unix { + return U(time.Now()) +} diff --git a/jsontime/jsontime.go b/jsontime/integer.go similarity index 53% rename from jsontime/jsontime.go rename to jsontime/integer.go index 9220f61..ffb9b88 100644 --- a/jsontime/jsontime.go +++ b/jsontime/integer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Tulir Asokan +// Copyright (c) 2023 Tulir Asokan // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -11,16 +11,18 @@ import ( "time" ) -func UM(time time.Time) UnixMilli { - return UnixMilli{Time: time} -} - -func UMInt(ts int64) UnixMilli { - return UM(time.UnixMilli(ts)) -} - -func UnixMilliNow() UnixMilli { - return UM(time.Now()) +func parseTime(data []byte, unixConv func(int64) time.Time, into *time.Time) error { + var val int64 + err := json.Unmarshal(data, &val) + if err != nil { + return nil + } + if val == 0 { + *into = time.Time{} + } else { + *into = unixConv(val) + } + return nil } type UnixMilli struct { @@ -35,25 +37,7 @@ func (um UnixMilli) MarshalJSON() ([]byte, error) { } func (um *UnixMilli) UnmarshalJSON(data []byte) error { - var val int64 - err := json.Unmarshal(data, &val) - if err != nil { - return err - } - if val == 0 { - um.Time = time.Time{} - } else { - um.Time = time.UnixMilli(val) - } - return nil -} - -func UMicro(time time.Time) UnixMicro { - return UnixMicro{Time: time} -} - -func UnixMicroNow() UnixMicro { - return UMicro(time.Now()) + return parseTime(data, time.UnixMilli, &um.Time) } type UnixMicro struct { @@ -68,29 +52,24 @@ func (um UnixMicro) MarshalJSON() ([]byte, error) { } func (um *UnixMicro) UnmarshalJSON(data []byte) error { - var val int64 - err := json.Unmarshal(data, &val) - if err != nil { - return err - } - if val == 0 { - um.Time = time.Time{} - } else { - um.Time = time.UnixMicro(val) - } - return nil + return parseTime(data, time.UnixMicro, &um.Time) } -func U(time time.Time) Unix { - return Unix{Time: time} +type UnixNano struct { + time.Time } -func UInt(ts int64) Unix { - return U(time.Unix(ts, 0)) +func (un UnixNano) MarshalJSON() ([]byte, error) { + if un.IsZero() { + return []byte{'0'}, nil + } + return json.Marshal(un.UnixNano()) } -func UnixNow() Unix { - return U(time.Now()) +func (un *UnixNano) UnmarshalJSON(data []byte) error { + return parseTime(data, func(i int64) time.Time { + return time.Unix(0, i) + }, &un.Time) } type Unix struct { @@ -105,15 +84,7 @@ func (u Unix) MarshalJSON() ([]byte, error) { } func (u *Unix) UnmarshalJSON(data []byte) error { - var val int64 - err := json.Unmarshal(data, &val) - if err != nil { - return err - } - if val == 0 { - u.Time = time.Time{} - } else { - u.Time = time.Unix(val, 0) - } - return nil + return parseTime(data, func(i int64) time.Time { + return time.Unix(i, 0) + }, &u.Time) } diff --git a/jsontime/string.go b/jsontime/string.go new file mode 100644 index 0000000..f02ce72 --- /dev/null +++ b/jsontime/string.go @@ -0,0 +1,95 @@ +// Copyright (c) 2023 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package jsontime + +import ( + "encoding/json" + "strconv" + "time" +) + +func parseTimeString(data []byte, unixConv func(int64) time.Time, into *time.Time) error { + var strVal string + err := json.Unmarshal(data, &strVal) + if err != nil { + return nil + } + val, err := strconv.ParseInt(strVal, 10, 64) + if err != nil { + return err + } + if val == 0 { + *into = time.Time{} + } else { + *into = unixConv(val) + } + return nil +} + +type UnixMilliString struct { + time.Time +} + +func (um UnixMilliString) MarshalJSON() ([]byte, error) { + if um.IsZero() { + return []byte{'"', '0', '"'}, nil + } + return json.Marshal(strconv.FormatInt(um.UnixMilli(), 10)) +} + +func (um *UnixMilliString) UnmarshalJSON(data []byte) error { + return parseTimeString(data, time.UnixMilli, &um.Time) +} + +type UnixMicroString struct { + time.Time +} + +func (um UnixMicroString) MarshalJSON() ([]byte, error) { + if um.IsZero() { + return []byte{'"', '0', '"'}, nil + } + return json.Marshal(strconv.FormatInt(um.UnixMilli(), 10)) +} + +func (um *UnixMicroString) UnmarshalJSON(data []byte) error { + return parseTimeString(data, time.UnixMicro, &um.Time) +} + +type UnixNanoString struct { + time.Time +} + +func (um UnixNanoString) MarshalJSON() ([]byte, error) { + if um.IsZero() { + return []byte{'"', '0', '"'}, nil + } + return json.Marshal(um.UnixNano()) +} + +func (um *UnixNanoString) UnmarshalJSON(data []byte) error { + return parseTimeString(data, func(i int64) time.Time { + return time.Unix(0, i) + }, &um.Time) +} + +type UnixString struct { + time.Time +} + +func (u UnixString) MarshalJSON() ([]byte, error) { + if u.IsZero() { + return []byte{'"', '0', '"'}, nil + } + return json.Marshal(u.Unix()) +} + +func (u *UnixString) UnmarshalJSON(data []byte) error { + return parseTime(data, func(i int64) time.Time { + return time.Unix(i, 0) + }, &u.Time) +}