From 6c4538408d5ad7995c1c168df82912c0f07d5dc9 Mon Sep 17 00:00:00 2001 From: Deardrops Date: Tue, 19 Nov 2019 20:52:00 -0800 Subject: [PATCH 1/4] types: Fix "Invalid time format" caused by daily saving time --- types/time.go | 2 +- types/time_test.go | 52 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/types/time.go b/types/time.go index eddbb34bd30a2..93917edacdbcc 100644 --- a/types/time.go +++ b/types/time.go @@ -1519,7 +1519,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(gotime.UTC); err != nil { return errors.Trace(err) } diff --git a/types/time_test.go b/types/time_test.go index 7a1995f9eee8a..89bee3b5fae58 100644 --- a/types/time_test.go +++ b/types/time_test.go @@ -1100,11 +1100,59 @@ 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") + rawLocal := time.Local + time.Local = losAngelesTz // Hack Local timezone + + tests = []struct { + tz *time.Location + input types.MysqlTime + expectRetError bool + }{{ + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 2, 0, 16, 0), + expectRetError: true, + }, { + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 1, 0, 50, 0), + expectRetError: false, + }, { + tz: losAngelesTz, + input: types.FromDate(2018, 3, 11, 3, 0, 20, 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, 1, 0, 50, 0), + expectRetError: false, + }, { + tz: shanghaiTz, + input: types.FromDate(2018, 3, 11, 3, 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)) + } + } + + time.Local = rawLocal } func (s *testTimeSuite) TestExtractDurationValue(c *C) { From d70684e22c35a4bd0c5e6b8ec4dd60b26965ee79 Mon Sep 17 00:00:00 2001 From: Deardrops Date: Tue, 19 Nov 2019 21:05:34 -0800 Subject: [PATCH 2/4] fixup --- types/time.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/time.go b/types/time.go index 93917edacdbcc..53b20d57b1ff4 100644 --- a/types/time.go +++ b/types/time.go @@ -1519,7 +1519,7 @@ func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error { return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) } - if _, err := t.GoTime(gotime.UTC); err != nil { + if _, err := t.GoTime(sc.TimeZone); err != nil { return errors.Trace(err) } From 4f8d8483eb4a5a4cdc69a5aed457fe269a240336 Mon Sep 17 00:00:00 2001 From: Deardrops Date: Tue, 19 Nov 2019 21:47:31 -0800 Subject: [PATCH 3/4] fixup CI --- types/time_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/types/time_test.go b/types/time_test.go index 89bee3b5fae58..bf25530b03752 100644 --- a/types/time_test.go +++ b/types/time_test.go @@ -1109,8 +1109,6 @@ func (s *testTimeSuite) TestCheckTimestamp(c *C) { // 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") - rawLocal := time.Local - time.Local = losAngelesTz // Hack Local timezone tests = []struct { tz *time.Location @@ -1151,8 +1149,6 @@ func (s *testTimeSuite) TestCheckTimestamp(c *C) { c.Assert(validTimestamp, IsNil, Commentf("For %s %s", t.input, t.tz)) } } - - time.Local = rawLocal } func (s *testTimeSuite) TestExtractDurationValue(c *C) { From 06065b7a15e146ddb97363becd5c4017a109fed3 Mon Sep 17 00:00:00 2001 From: Deardrops Date: Tue, 19 Nov 2019 22:49:01 -0800 Subject: [PATCH 4/4] address comment --- types/time_test.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/types/time_test.go b/types/time_test.go index bf25530b03752..4d23f198b683b 100644 --- a/types/time_test.go +++ b/types/time_test.go @@ -1109,35 +1109,48 @@ func (s *testTimeSuite) TestCheckTimestamp(c *C) { // 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, 2, 0, 16, 0), - expectRetError: true, - }, { 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, 2, 0, 16, 0), + input: types.FromDate(2018, 3, 11, 1, 0, 50, 0), expectRetError: false, }, { tz: shanghaiTz, - input: types.FromDate(2018, 3, 11, 1, 0, 50, 0), + 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, }, }