mirror of
https://github.com/jimeh/go-tyme.git
synced 2026-02-19 01:46:41 +00:00
80 lines
2.1 KiB
Go
80 lines
2.1 KiB
Go
package tyme
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// TimeRFC3339 is a wrapper around time.Time that implements JSON/YAML
|
|
// marshaling/unmarshaling interfaces. As opposed to Time, only RFC 3339
|
|
// formatted input is accepted when unmarshaling.
|
|
//
|
|
// It marshals to a string in RFC 3339 format, with sub-second precision added
|
|
// if present.
|
|
//
|
|
// It will only unmarshal from a string in RFC 3339 format. Any other format
|
|
// will cause an unmarshaling error.
|
|
type TimeRFC3339 time.Time
|
|
|
|
// RFC3339NanoJSON is the time.RFC3339Nano format with double quotes around it.
|
|
const RFC3339NanoJSON = `"` + time.RFC3339Nano + `"`
|
|
|
|
// MarshalJSON implements the json.Marshaler interface, and formats the time as
|
|
// a JSON string in RFC 3339 format, with sub-second precision added if
|
|
// present.
|
|
func (t TimeRFC3339) MarshalJSON() ([]byte, error) {
|
|
return []byte(time.Time(t).Format(RFC3339NanoJSON)), nil
|
|
}
|
|
|
|
// UnmarshalJSON implements the json.Unmarshaler interface, and parses a
|
|
// JSON string in RFC 3339 format, with sub-second precision added if
|
|
// present.
|
|
func (t *TimeRFC3339) UnmarshalJSON(b []byte) error {
|
|
s, err := strconv.Unquote(string(b))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
nt, err := time.Parse(time.RFC3339Nano, s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*t = TimeRFC3339(nt)
|
|
|
|
return err
|
|
}
|
|
|
|
// MarshalYAML implements the yaml.Marshaler interface, and formats the time as
|
|
// a YAML timestamp type in RFC 3339 string format, with sub-second precision
|
|
// added if present.
|
|
func (t TimeRFC3339) MarshalYAML() (interface{}, error) {
|
|
return time.Time(t), nil
|
|
}
|
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaler interface, and parses a YAML
|
|
// timestamp or string formatted according to RFC 3339, with sub-second
|
|
// precision added if present.
|
|
func (t *TimeRFC3339) UnmarshalYAML(node *yaml.Node) error {
|
|
var nt time.Time
|
|
var err error
|
|
|
|
switch node.Tag {
|
|
case "!!timestamp":
|
|
err = node.Decode(&nt)
|
|
case "!!str":
|
|
nt, err = time.Parse(time.RFC3339Nano, node.Value)
|
|
default:
|
|
return &yaml.TypeError{Errors: []string{"invalid time format"}}
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*t = TimeRFC3339(nt)
|
|
|
|
return nil
|
|
}
|