Moved shared OpenMeteo time parsing code into a shared internal/providers/openmeteo library.

This commit is contained in:
2026-01-15 10:17:56 -06:00
parent 675c5a6117
commit e92577c30e
4 changed files with 91 additions and 56 deletions

View File

@@ -11,6 +11,7 @@ import (
"gitea.maximumdirect.net/ejr/feedkit/config"
"gitea.maximumdirect.net/ejr/feedkit/event"
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/providers/openmeteo"
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/sources/common"
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/standards"
)
@@ -103,7 +104,9 @@ func (s *ObservationSource) fetchRaw(ctx context.Context) (json.RawMessage, open
return raw, openMeteoMeta{}, nil
}
if t, err := parseOpenMeteoTime(meta.Current.Time, meta.Timezone, meta.UTCOffsetSeconds); err == nil {
// Best effort: compute a stable EffectiveAt + event ID component.
// If parsing fails, we simply omit EffectiveAt and fall back to time.Now() in buildEventID.
if t, err := openmeteo.ParseTime(meta.Current.Time, meta.Timezone, meta.UTCOffsetSeconds); err == nil {
meta.ParsedTimestamp = t.UTC()
}
@@ -125,25 +128,3 @@ func buildEventID(sourceName string, meta openMeteoMeta) string {
return fmt.Sprintf("openmeteo:current:%s:%s:%s", sourceName, locKey, ts.Format(time.RFC3339Nano))
}
func parseOpenMeteoTime(s string, tz string, utcOffsetSeconds int) (time.Time, error) {
s = strings.TrimSpace(s)
if s == "" {
return time.Time{}, fmt.Errorf("empty time")
}
if t, err := time.Parse(time.RFC3339, s); err == nil {
return t, nil
}
const layout = "2006-01-02T15:04"
if tz != "" {
if loc, err := time.LoadLocation(tz); err == nil {
return time.ParseInLocation(layout, s, loc)
}
}
loc := time.FixedZone("open-meteo", utcOffsetSeconds)
return time.ParseInLocation(layout, s, loc)
}