diff --git a/reader/date/parser.go b/reader/date/parser.go index bc55ada2..a0488ef4 100644 --- a/reader/date/parser.go +++ b/reader/date/parser.go @@ -6,6 +6,7 @@ package date // import "miniflux.app/reader/date" import ( "errors" "fmt" + "math" "strconv" "strings" "time" @@ -315,11 +316,13 @@ func Parse(rawInput string) (t time.Time, err error) { switch layout { case time.RFC822, time.RFC850, time.RFC1123: if t, err = parseLocalTimeDates(layout, processedInput); err == nil { + t = checkTimezoneRange(t) return } } if t, err = time.Parse(layout, processedInput); err == nil { + t = checkTimezoneRange(t) return } } @@ -347,3 +350,14 @@ func parseLocalTimeDates(layout, ds string) (t time.Time, err error) { return time.ParseInLocation(layout, ds, loc) } + +// https://en.wikipedia.org/wiki/List_of_UTC_offsets +// Offset range: westernmost (−12:00) to the easternmost (+14:00) +// Avoid "pq: time zone displacement out of range" errors +func checkTimezoneRange(t time.Time) time.Time { + _, offset := t.Zone() + if math.Abs(float64(offset)) > 14*60*60 { + t = t.UTC() + } + return t +} diff --git a/reader/date/parser_test.go b/reader/date/parser_test.go index 0056dcb5..aa0850a2 100644 --- a/reader/date/parser_test.go +++ b/reader/date/parser_test.go @@ -187,3 +187,16 @@ func TestParseWeirdDateFormat(t *testing.T) { } } } + +func TestParseDateWithTimezoneOutOfRange(t *testing.T) { + date, err := Parse("2023-05-29 00:00:00-23:00") + + if err != nil { + t.Errorf(`Unable to parse date: %v`, err) + } + + _, offset := date.Zone() + if offset != 0 { + t.Errorf(`The offset should be reinitialized to 0 instead of %v because it's out of range`, offset) + } +}