From 667afd9dca52123837af67c54f8866217368bd30 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 24 Jul 2020 15:24:33 +0800 Subject: [PATCH] types: fix STR_TO_DATE handling for %h, %r (#18171) (#18428) (#18725) Signed-off-by: ti-srebot --- types/format_test.go | 13 +++++++------ types/time.go | 9 +++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/types/format_test.go b/types/format_test.go index 642713476e833..91dc4f8344032 100644 --- a/types/format_test.go +++ b/types/format_test.go @@ -89,9 +89,11 @@ func (s *testTimeSuite) TestStrToDate(c *C) { {`a09:30:17`, `a%h:%i:%s`, types.FromDate(0, 0, 0, 9, 30, 17, 0)}, {`09:30:17a`, `%h:%i:%s`, types.FromDate(0, 0, 0, 9, 30, 17, 0)}, {`abc`, `abc`, types.ZeroTime}, + {`12:43:24`, `%h:%i:%s`, types.FromDate(0, 0, 0, 0, 43, 24, 0)}, {`09`, `%m`, types.FromDate(0, 9, 0, 0, 0, 0, 0)}, {`09`, `%s`, types.FromDate(0, 0, 0, 0, 0, 9, 0)}, - {`12:43:24 AM`, `%r`, types.FromDate(0, 0, 0, 12, 43, 24, 0)}, + {`12:43:24 AM`, `%r`, types.FromDate(0, 0, 0, 0, 43, 24, 0)}, + {`12:43:24 PM`, `%r`, types.FromDate(0, 0, 0, 12, 43, 24, 0)}, {`11:43:24 PM`, `%r`, types.FromDate(0, 0, 0, 23, 43, 24, 0)}, {`00:12:13`, `%T`, types.FromDate(0, 0, 0, 0, 12, 13, 0)}, {`23:59:59`, `%T`, types.FromDate(0, 0, 0, 23, 59, 59, 0)}, @@ -129,9 +131,8 @@ func (s *testTimeSuite) TestStrToDate(c *C) { }{ {`04/31/2004`, `%m/%d/%Y`}, {`a09:30:17`, `%h:%i:%s`}, // format mismatch - {`12:43:24 PM`, `%r`}, - {`12:43:24`, `%r`}, // no PM or AM followed - {`23:60:12`, `%T`}, // invalid minute + {`12:43:24`, `%r`}, // no PM or AM followed + {`23:60:12`, `%T`}, // invalid minute {`18`, `%l`}, {`00:21:22 AM`, `%h:%i:%s %p`}, {`100/10/22`, `%y/%m/%d`}, @@ -139,8 +140,8 @@ func (s *testTimeSuite) TestStrToDate(c *C) { {"2010-11-12 13 am", `%Y-%m-%d %h %p`}, {"2010-11-12 0 am", `%Y-%m-%d %h %p`}, } - for _, tt := range errTests { + for i, tt := range errTests { var t types.Time - c.Assert(t.StrToDate(sc, tt.input, tt.format), IsFalse) + c.Assert(t.StrToDate(sc, tt.input, tt.format), IsFalse, Commentf("no.%d failed", i)) } } diff --git a/types/time.go b/types/time.go index ab8fa43beab0b..9a874597db4c5 100644 --- a/types/time.go +++ b/types/time.go @@ -2190,6 +2190,10 @@ func mysqlTimeFix(t *MysqlTime, ctx map[string]int) error { if valueAMorPm == constForPM { t.hour += 12 } + } else { + if _, ok := ctx["%h"]; ok && t.Hour() == 12 { + t.hour = 0 + } } return nil } @@ -2405,6 +2409,10 @@ func time12Hour(t *MysqlTime, input string, ctx map[string]int) (string, bool) { if !succ || hour > 12 || hour == 0 || input[2] != ':' { return input, false } + // 12:34:56 AM -> 00:34:56 + if hour == 12 { + hour = 0 + } minute, succ := parseDigits(input[3:], 2) if !succ || minute > 59 || input[5] != ':' { @@ -2550,6 +2558,7 @@ func hour12Numeric(t *MysqlTime, input string, ctx map[string]int) (string, bool return input, false } t.hour = v + ctx["%h"] = v return input[length:], true }