From d7b990467fde50dd406e6429d2e7f08d53a20a20 Mon Sep 17 00:00:00 2001 From: Guo Song Date: Sun, 5 May 2019 13:34:49 +0800 Subject: [PATCH 1/2] fix leap year --- types/time.go | 6 +++--- types/time_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/types/time.go b/types/time.go index f9b2083842840..09a4c51463040 100644 --- a/types/time.go +++ b/types/time.go @@ -1474,7 +1474,7 @@ func checkDateRange(t MysqlTime) error { func checkMonthDay(year, month, day int, allowInvalidDate bool) error { if month < 0 || month > 12 { - return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(month)) + return errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(month)) } maxDay := 31 @@ -1482,13 +1482,13 @@ func checkMonthDay(year, month, day int, allowInvalidDate bool) error { if month > 0 { maxDay = maxDaysInMonth[month-1] } - if month == 2 && year%4 != 0 { + if month == 2 && (year%4 != 0 || (year%100 == 0 && year%400 != 0)) { maxDay = 28 } } if day < 0 || day > maxDay { - return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(day)) + return errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(day)) } return nil } diff --git a/types/time_test.go b/types/time_test.go index c23c0032204c6..28aea65741579 100644 --- a/types/time_test.go +++ b/types/time_test.go @@ -1455,3 +1455,43 @@ func (s *testTimeSuite) TestTimeSub(c *C) { c.Assert(rec, Equals, dur) } } + +func (s *testTimeSuite) TestCheckMonthDay(c *C) { + dates := []struct { + date types.MysqlTime + isValidDate bool + }{ + {types.FromDate(1900, 2, 29, 0, 0, 0, 0), false}, + {types.FromDate(1900, 2, 28, 0, 0, 0, 0), true}, + {types.FromDate(2000, 2, 29, 0, 0, 0, 0), true}, + {types.FromDate(2000, 1, 1, 0, 0, 0, 0), true}, + {types.FromDate(1900, 1, 1, 0, 0, 0, 0), true}, + {types.FromDate(1900, 1, 31, 0, 0, 0, 0), true}, + {types.FromDate(1900, 4, 1, 0, 0, 0, 0), true}, + {types.FromDate(1900, 4, 31, 0, 0, 0, 0), false}, + {types.FromDate(1900, 4, 30, 0, 0, 0, 0), true}, + {types.FromDate(2000, 2, 30, 0, 0, 0, 0), false}, + {types.FromDate(2000, 13, 1, 0, 0, 0, 0), false}, + {types.FromDate(4000, 2, 29, 0, 0, 0, 0), true}, + {types.FromDate(3200, 2, 29, 0, 0, 0, 0), true}, + } + + sc := &stmtctx.StatementContext{ + TimeZone: time.UTC, + AllowInvalidDate: false, + } + + for _, t := range dates { + tt := types.Time{ + Time: t.date, + Type: mysql.TypeDate, + Fsp: types.DefaultFsp, + } + err := tt.Check(sc) + if t.isValidDate { + c.Check(err, IsNil) + } else { + c.Check(types.ErrIncorrectDatetimeValue.Equal(err), IsTrue) + } + } +} From a8bd4f453c8bc40de52f88b64d43d95b30a18365 Mon Sep 17 00:00:00 2001 From: Guo Song Date: Sun, 5 May 2019 13:58:21 +0800 Subject: [PATCH 2/2] use isLeapYear --- types/time.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/time.go b/types/time.go index 09a4c51463040..25f24b95eaf5c 100644 --- a/types/time.go +++ b/types/time.go @@ -1482,7 +1482,7 @@ func checkMonthDay(year, month, day int, allowInvalidDate bool) error { if month > 0 { maxDay = maxDaysInMonth[month-1] } - if month == 2 && (year%4 != 0 || (year%100 == 0 && year%400 != 0)) { + if month == 2 && !isLeapYear(uint16(year)) { maxDay = 28 } }