From bac76bbebac37e9dd813c10b1addfc4972bab122 Mon Sep 17 00:00:00 2001 From: AmPlace <81105770+AmPlace@users.noreply.github.com> Date: Wed, 12 Aug 2026 03:53:01 +0800 Subject: [PATCH 1/2] fix(189pc): support new cloud time format Co-Authored-By: Codex --- drivers/189pc/help.go | 8 ++++- drivers/189pc/help_test.go | 65 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 drivers/189pc/help_test.go diff --git a/drivers/189pc/help.go b/drivers/189pc/help.go index 6f6c59f30..c4dd1ad80 100644 --- a/drivers/189pc/help.go +++ b/drivers/189pc/help.go @@ -116,9 +116,15 @@ func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error { } func (t *Time) Unmarshal(b []byte) error { bs := strings.Trim(string(b), "\"") + bs = strings.ReplaceAll(bs, "\u202f", " ") + bs = strings.ReplaceAll(bs, "\u00a0", " ") var v time.Time var err error - for _, f := range []string{"2006-01-02 15:04:05 -07", "Jan 2, 2006 15:04:05 PM -07"} { + for _, f := range []string{ + "2006-01-02 15:04:05 -07", + "Jan 2, 2006 15:04:05 PM -07", + "Jan 2, 2006, 3:04:05 PM -07", + } { v, err = time.ParseInLocation(f, bs+" +08", time.Local) if err == nil { break diff --git a/drivers/189pc/help_test.go b/drivers/189pc/help_test.go new file mode 100644 index 000000000..6faa8860a --- /dev/null +++ b/drivers/189pc/help_test.go @@ -0,0 +1,65 @@ +package _189pc + +import ( + "testing" + "time" +) + +func TestTimeUnmarshal(t *testing.T) { + tests := []struct { + name string + input string + want time.Time + }{ + { + name: "numeric date", + input: "2026-08-12 03:32:44", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + { + name: "legacy month date", + input: "Aug 12, 2026 15:32:44 PM", + want: time.Date(2026, time.August, 12, 15, 32, 44, 0, time.Local), + }, + { + name: "updated month date", + input: "Aug 12, 2026, 3:32:44 AM", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + { + name: "narrow no-break space before meridiem", + input: "Aug 12, 2026, 3:32:44\u202fAM", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + { + name: "no-break space before meridiem", + input: "Aug 12, 2026, 3:32:44\u00a0AM", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got Time + if err := got.Unmarshal([]byte(tt.input)); err != nil { + t.Fatalf("Time.Unmarshal(%q) returned error: %v", tt.input, err) + } + gotTime := time.Time(got) + gotYear, gotMonth, gotDay := gotTime.Date() + wantYear, wantMonth, wantDay := tt.want.Date() + gotHour, gotMinute, gotSecond := gotTime.Clock() + wantHour, wantMinute, wantSecond := tt.want.Clock() + if gotYear != wantYear || gotMonth != wantMonth || gotDay != wantDay || + gotHour != wantHour || gotMinute != wantMinute || gotSecond != wantSecond { + t.Fatalf("Time.Unmarshal(%q) = %v, want %v", tt.input, gotTime, tt.want) + } + }) + } +} + +func TestTimeUnmarshalRejectsInvalidTime(t *testing.T) { + var got Time + if err := got.Unmarshal([]byte("Aug 12, 2026, 25:32:44 AM")); err == nil { + t.Fatal("Time.Unmarshal accepted an invalid time") + } +} From eba0ae1b6baa2db5527e625fb18cdb2299c03468 Mon Sep 17 00:00:00 2001 From: AmPlace <81105770+AmPlace@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:04:41 +0800 Subject: [PATCH 2/2] fix(189tv): support updated cloud time format - Normalize Unicode spaces and preserve existing time layouts. - Add the updated 12-hour layout and focused parser regression tests. Co-Authored-By: Codex <267193182+codex@users.noreply.github.com> --- drivers/189_tv/help.go | 8 ++++- drivers/189_tv/help_test.go | 70 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 drivers/189_tv/help_test.go diff --git a/drivers/189_tv/help.go b/drivers/189_tv/help.go index cfd9e18ab..2fecaf65b 100644 --- a/drivers/189_tv/help.go +++ b/drivers/189_tv/help.go @@ -72,9 +72,15 @@ func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error { } func (t *Time) Unmarshal(b []byte) error { bs := strings.Trim(string(b), "\"") + bs = strings.ReplaceAll(bs, "\u202f", " ") + bs = strings.ReplaceAll(bs, "\u00a0", " ") var v time.Time var err error - for _, f := range []string{"2006-01-02 15:04:05 -07", "Jan 2, 2006 15:04:05 PM -07"} { + for _, f := range []string{ + "2006-01-02 15:04:05 -07", + "Jan 2, 2006 15:04:05 PM -07", + "Jan 2, 2006, 3:04:05 PM -07", + } { v, err = time.ParseInLocation(f, bs+" +08", time.Local) if err == nil { break diff --git a/drivers/189_tv/help_test.go b/drivers/189_tv/help_test.go new file mode 100644 index 000000000..f6f86d331 --- /dev/null +++ b/drivers/189_tv/help_test.go @@ -0,0 +1,70 @@ +package _189_tv + +import ( + "testing" + "time" +) + +func TestTimeUnmarshal(t *testing.T) { + tests := []struct { + name string + input string + want time.Time + }{ + { + name: "numeric date", + input: "2026-08-12 03:32:44", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + { + name: "legacy month date", + input: "Aug 12, 2026 15:32:44 PM", + want: time.Date(2026, time.August, 12, 15, 32, 44, 0, time.Local), + }, + { + name: "updated format with AM", + input: "Aug 12, 2026, 12:35:41 AM", + want: time.Date(2026, time.August, 12, 0, 35, 41, 0, time.Local), + }, + { + name: "updated format with PM", + input: "Aug 12, 2026, 3:32:44 PM", + want: time.Date(2026, time.August, 12, 15, 32, 44, 0, time.Local), + }, + { + name: "narrow no-break space", + input: "Aug 12, 2026, 3:32:44\u202fPM", + want: time.Date(2026, time.August, 12, 15, 32, 44, 0, time.Local), + }, + { + name: "no-break space", + input: "Aug 12, 2026, 3:32:44\u00a0AM", + want: time.Date(2026, time.August, 12, 3, 32, 44, 0, time.Local), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got Time + if err := got.Unmarshal([]byte(tt.input)); err != nil { + t.Fatalf("Time.Unmarshal(%q) returned error: %v", tt.input, err) + } + gotTime := time.Time(got) + gotYear, gotMonth, gotDay := gotTime.Date() + wantYear, wantMonth, wantDay := tt.want.Date() + gotHour, gotMinute, gotSecond := gotTime.Clock() + wantHour, wantMinute, wantSecond := tt.want.Clock() + if gotYear != wantYear || gotMonth != wantMonth || gotDay != wantDay || + gotHour != wantHour || gotMinute != wantMinute || gotSecond != wantSecond { + t.Fatalf("Time.Unmarshal(%q) = %v, want %v", tt.input, gotTime, tt.want) + } + }) + } +} + +func TestTimeUnmarshalRejectsInvalidTime(t *testing.T) { + var got Time + if err := got.Unmarshal([]byte("Aug 12, 2026, 25:32:44 PM")); err == nil { + t.Fatal("Time.Unmarshal accepted an invalid time") + } +}