Skip to content

Commit

Permalink
types: Fix checkMonthDay() to correctly handle leap year (#10342)
Browse files Browse the repository at this point in the history
  • Loading branch information
erjiaqing authored and zz-jason committed May 5, 2019
1 parent 68e7b00 commit c9f0a1c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
6 changes: 3 additions & 3 deletions types/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -1474,21 +1474,21 @@ 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
if !allowInvalidDate {
if month > 0 {
maxDay = maxDaysInMonth[month-1]
}
if month == 2 && year%4 != 0 {
if month == 2 && !isLeapYear(uint16(year)) {
maxDay = 28
}
}

if day < 0 || day > maxDay {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(day))
return errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(day))
}
return nil
}
Expand Down
40 changes: 40 additions & 0 deletions types/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

0 comments on commit c9f0a1c

Please sign in to comment.