feat: migrate to golang
This commit is contained in:
62
internal/model/time.go
Normal file
62
internal/model/time.go
Normal file
@ -0,0 +1,62 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// timeLayouts are tried in order when parsing a persisted timestamp. The
|
||||
// first two cover what this Go implementation itself writes (time zone
|
||||
// aware); the rest cover what the original Python implementation wrote via
|
||||
// datetime.now().isoformat() — no time zone, and microseconds included only
|
||||
// when non-zero (Go's parser accepts an optional fractional-seconds suffix
|
||||
// even when the layout doesn't specify one, so a single no-fraction layout
|
||||
// handles both cases).
|
||||
var timeLayouts = []string{
|
||||
time.RFC3339Nano,
|
||||
time.RFC3339,
|
||||
"2006-01-02T15:04:05",
|
||||
}
|
||||
|
||||
// Time wraps time.Time to support reading timestamps in both this Go
|
||||
// implementation's own format and the original Python implementation's
|
||||
// timezone-naive datetime.isoformat() format (e.g.
|
||||
// "2026-03-19T18:21:47.740090"), which Go's default time.Time YAML/text
|
||||
// decoding rejects outright since it strictly requires RFC3339 (with a zone
|
||||
// offset).
|
||||
type Time struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// UnmarshalYAML tries each supported layout in turn.
|
||||
func (t *Time) UnmarshalYAML(value *yaml.Node) error {
|
||||
var s string
|
||||
if err := value.Decode(&s); err != nil {
|
||||
return err
|
||||
}
|
||||
if s == "" {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for _, layout := range timeLayouts {
|
||||
parsed, err := time.Parse(layout, s)
|
||||
if err == nil {
|
||||
t.Time = parsed
|
||||
return nil
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
return fmt.Errorf("cannot parse time %q: %w", s, lastErr)
|
||||
}
|
||||
|
||||
// MarshalYAML writes the timestamp in RFC3339Nano (timezone-aware) format.
|
||||
func (t Time) MarshalYAML() (interface{}, error) {
|
||||
if t.Time.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
return t.Time.Format(time.RFC3339Nano), nil
|
||||
}
|
||||
Reference in New Issue
Block a user