diff --git a/go/vehicle-gateway/internal/history/query.go b/go/vehicle-gateway/internal/history/query.go index 12dfaeb3..a78628c4 100644 --- a/go/vehicle-gateway/internal/history/query.go +++ b/go/vehicle-gateway/internal/history/query.go @@ -810,6 +810,9 @@ func normalizeDateTimeLiteral(value string) string { if len(value) == len("2006-01-02T15:04:05") && value[10] == 'T' { return value[:10] + " " + value[11:] } + if parsed, err := time.Parse(time.RFC3339, value); err == nil { + return parsed.In(time.FixedZone("Asia/Shanghai", 8*3600)).Format("2006-01-02 15:04:05") + } return value } diff --git a/go/vehicle-gateway/internal/history/query_test.go b/go/vehicle-gateway/internal/history/query_test.go index bd657c0d..ed4b0f12 100644 --- a/go/vehicle-gateway/internal/history/query_test.go +++ b/go/vehicle-gateway/internal/history/query_test.go @@ -268,6 +268,17 @@ func TestParseRawFrameQueryAcceptsDatetimeLocalValues(t *testing.T) { } } +func TestNormalizeDateTimeLiteralConvertsRFC3339ToShanghaiTime(t *testing.T) { + for raw, want := range map[string]string{ + "2026-07-01T00:00:00+08:00": "2026-07-01 00:00:00", + "2026-06-30T16:00:00Z": "2026-07-01 00:00:00", + } { + if got := normalizeDateTimeLiteral(raw); got != want { + t.Fatalf("normalizeDateTimeLiteral(%q) = %q, want %q", raw, got, want) + } + } +} + func TestParseMessageIDSupportsDecimalAndHex(t *testing.T) { for raw, want := range map[string]int64{ "512": 512,