diff --git a/types/time.go b/types/time.go index ed014288e0fb5..6ee0799294cd1 100644 --- a/types/time.go +++ b/types/time.go @@ -1533,7 +1533,7 @@ func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error { return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) } - if _, err := t.GoTime(gotime.Local); err != nil { + if _, err := t.GoTime(sc.TimeZone); err != nil { return errors.Trace(err) } diff --git a/types/time_test.go b/types/time_test.go index 92120b6cac459..f9e3dd20a57ff 100644 --- a/types/time_test.go +++ b/types/time_test.go @@ -1101,9 +1101,66 @@ func (s *testTimeSuite) TestCheckTimestamp(c *C) { for _, t := range tests { validTimestamp := types.CheckTimestampTypeForTest(&stmtctx.StatementContext{TimeZone: t.tz}, t.input) if t.expectRetError { - c.Assert(validTimestamp, NotNil, Commentf("For %s", t.input)) + c.Assert(validTimestamp, NotNil, Commentf("For %s %s", t.input, t.tz)) } else { - c.Assert(validTimestamp, IsNil, Commentf("For %s", t.input)) + c.Assert(validTimestamp, IsNil, Commentf("For %s %s", t.input, t.tz)) + } + } + + // Issue #13605: "Invalid time format" caused by time zone issue + // Some regions like Los Angeles use daylight saving time, see https://en.wikipedia.org/wiki/Daylight_saving_time + losAngelesTz, _ := time.LoadLocation("America/Los_Angeles") + LondonTz, _ := time.LoadLocation("Europe/London") + + tests = []struct { + tz *time.Location + input types.MysqlTime + expectRetError bool + }{{ + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 1, 0, 50, 0), + expectRetError: false, + }, { + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 2, 0, 16, 0), + expectRetError: true, + }, { + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 3, 0, 20, 0), + expectRetError: false, + }, { + tz: shanghaiTz, + input: types.FromDate(2018, 3, 11, 1, 0, 50, 0), + expectRetError: false, + }, { + tz: shanghaiTz, + input: types.FromDate(2018, 3, 11, 2, 0, 16, 0), + expectRetError: false, + }, { + tz: shanghaiTz, + input: types.FromDate(2018, 3, 11, 3, 0, 20, 0), + expectRetError: false, + }, { + tz: LondonTz, + input: types.FromDate(2019, 3, 31, 0, 0, 20, 0), + expectRetError: false, + }, { + tz: LondonTz, + input: types.FromDate(2019, 3, 31, 1, 0, 20, 0), + expectRetError: true, + }, { + tz: LondonTz, + input: types.FromDate(2019, 3, 31, 2, 0, 20, 0), + expectRetError: false, + }, + } + + for _, t := range tests { + validTimestamp := types.CheckTimestampTypeForTest(&stmtctx.StatementContext{TimeZone: t.tz}, t.input) + if t.expectRetError { + c.Assert(validTimestamp, NotNil, Commentf("For %s %s", t.input, t.tz)) + } else { + c.Assert(validTimestamp, IsNil, Commentf("For %s %s", t.input, t.tz)) } } }