Files
go-tyme/time.go

76 lines
1.7 KiB
Go

package tyme
import (
"strconv"
"time"
"gopkg.in/yaml.v3"
)
// Time is a wrapper around time.Time that implements JSON and YAML
// marshaler and unmarshaler interfaces.
//
// It marshals to a string in RFC 3339 format, with sub-second
// precision added if present.
//
// It unmarshals from a wide range of string date and time formats, by using the
// dateparse package.
type Time time.Time
// 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 Time) MarshalJSON() ([]byte, error) {
return []byte(time.Time(t).Format(RFC3339NanoJSON)), nil
}
// UnmarshalJSON implements the json.Unmarshaler interface, and parses a wide
// range of string date and time formats, by using the dateparse package.
func (t *Time) UnmarshalJSON(b []byte) error {
s, err := strconv.Unquote(string(b))
if err != nil {
return err
}
nt, err := Parse(s)
if err != nil {
return err
}
*t = 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 Time) MarshalYAML() (interface{}, error) {
return time.Time(t), nil
}
// UnmarshalYAML implements the yaml.Unmarshaler interface, and parses a wide
// range of date and time formats, by using the dateparse package.
func (t *Time) UnmarshalYAML(node *yaml.Node) error {
var nt Time
var err error
switch node.Tag {
case "!!timestamp":
var tt time.Time
err = node.Decode(&tt)
nt = Time(tt)
case "!!str":
nt, err = Parse(node.Value)
default:
return &yaml.TypeError{Errors: []string{"invalid time format"}}
}
if err != nil {
return err
}
*t = nt
return nil
}