package main import ( "errors" "strings" "time" ) type TimeComponent struct { TS *string `parser:"@Time"` } func (t TimeComponent) Time() (time.Time, error) { if strings.HasSuffix(*t.TS, "Z") { return time.ParseInLocation("15:04:05Z", *t.TS, time.UTC) } return time.ParseInLocation("15:04:05", *t.TS, time.Local) } func (t TimeComponent) RequiresRefreshing() bool { return false } type DateWithTimeComponents struct { Date *string `parser:"@Date"` MaybeTime *TimeComponent `parser:" @@?"` } func (d DateWithTimeComponents) Time() (time.Time, error) { t, err := time.Parse("2006-01-02", *d.Date) if err != nil { return time.Time{}, err } if d.MaybeTime != nil { tt, err := d.MaybeTime.Time() if err != nil { return time.Time{}, err } t = t.Add(tt.Sub(tt.Truncate(24 * time.Hour))) } return t, nil } type Timestamp struct { Full *string `parser:"@Timestamp"` DT *DateWithTimeComponents `parser:"| @@"` TimeToday *TimeComponent `parser:" | @@"` Int *int `parser:" | @Int"` } func (t Timestamp) Time() (time.Time, error) { switch { case t.Full != nil: if strings.HasSuffix(*t.Full, "Z") { return time.ParseInLocation("2006-01-02T15:04:05Z", *t.Full, time.UTC) } return time.ParseInLocation("2006-01-02T15:04:05", *t.Full, time.Local) case t.DT != nil: return t.DT.Time() case t.TimeToday != nil: tt, err := t.TimeToday.Time() if err != nil { return time.Time{}, err } today := time.Now().In(tt.Location()) return time.Date(today.Year(), today.Month(), today.Day(), tt.Hour(), tt.Minute(), tt.Second(), tt.Nanosecond(), tt.Location()), nil } return time.Unix(int64(*t.Int), 0), nil } func (t Timestamp) RequiresRefreshing() bool { return false } type Atom struct { Timestamp *Timestamp `parser:"@@"` Identifier *string `parser:" | @Identifier"` } func (a Atom) Time() (time.Time, error) { switch { case a.Timestamp != nil: return a.Timestamp.Time() case a.Identifier != nil: if *a.Identifier == "now" { return time.Now(), nil } return time.Time{}, errors.New("unknown identifier") } return time.Time{}, errors.New("unhandled case") } func (a Atom) RequiresRefreshing() bool { switch { case a.Timestamp != nil: return a.Timestamp.RequiresRefreshing() case a.Identifier != nil: if *a.Identifier == "now" { return true } return false } return false }