diff --git a/internal/timezone/timezone.go b/internal/timezone/timezone.go index 3c7fa7c2..c0746945 100644 --- a/internal/timezone/timezone.go +++ b/internal/timezone/timezone.go @@ -12,10 +12,14 @@ func Convert(tz string, t time.Time) time.Time { userTimezone := getLocation(tz) if t.Location().String() == "" { + if t.Before(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)) { + return time.Date(0, time.January, 1, 0, 0, 0, 0, userTimezone) + } + // In this case, the provided date is already converted to the user timezone by Postgres, // but the timezone information is not set in the time struct. // We cannot use time.In() because the date will be converted a second time. - t = time.Date( + return time.Date( t.Year(), t.Month(), t.Day(), @@ -26,7 +30,7 @@ func Convert(tz string, t time.Time) time.Time { userTimezone, ) } else if t.Location() != userTimezone { - t = t.In(userTimezone) + return t.In(userTimezone) } return t diff --git a/internal/timezone/timezone_test.go b/internal/timezone/timezone_test.go index 49957b7a..82249cdb 100644 --- a/internal/timezone/timezone_test.go +++ b/internal/timezone/timezone_test.go @@ -75,3 +75,17 @@ func TestConvertTimeWithIdenticalTimezone(t *testing.T) { t.Fatalf(`Unexpected time, got hours=%d, minutes=%d, secs=%d`, hours, minutes, secs) } } + +func TestConvertPostgresDateTimeWithNegativeTimezoneOffset(t *testing.T) { + tz := "US/Eastern" + input := time.Date(0, 1, 1, 0, 0, 0, 0, time.FixedZone("", -5)) + output := Convert(tz, input) + + if output.Location().String() != tz { + t.Fatalf(`Unexpected timezone, got %q instead of %s`, output.Location(), tz) + } + + if year := output.Year(); year != 0 { + t.Fatalf(`Unexpected year, got %d instead of 0`, year) + } +}