@@ -2152,8 +2152,8 @@ var dateFormatParserTable = map[string]dateFormatParser{
21522152 "%e" : dayOfMonthNumeric , // Day of the month, numeric (0..31)
21532153 "%f" : microSeconds , // Microseconds (000000..999999)
21542154 "%h" : hour24TwoDigits , // Hour (01..12)
2155- "%H" : hour24TwoDigits , // Hour (01..12 )
2156- "%I" : hour24TwoDigits , // Hour (01..12)
2155+ "%H" : hour24Numeric , // Hour (00..23 )
2156+ "%I" : hour12Numeric , // Hour (01..12)
21572157 "%i" : minutesNumeric , // Minutes, numeric (00..59)
21582158 "%j" : dayOfYearThreeDigits , // Day of year (001..366)
21592159 "%k" : hour24Numeric , // Hour (0..23)
@@ -2257,21 +2257,27 @@ func hour24TwoDigits(t *MysqlTime, input string, ctx map[string]int) (string, bo
22572257}
22582258
22592259func secondsNumeric (t * MysqlTime , input string , ctx map [string ]int ) (string , bool ) {
2260- v , succ := parseDigits (input , 2 )
2260+ result := oneOrTwoDigitRegex .FindString (input )
2261+ length := len (result )
2262+
2263+ v , succ := parseDigits (input , length )
22612264 if ! succ || v >= 60 {
22622265 return input , false
22632266 }
22642267 t .second = uint8 (v )
2265- return input [2 :], true
2268+ return input [length :], true
22662269}
22672270
22682271func minutesNumeric (t * MysqlTime , input string , ctx map [string ]int ) (string , bool ) {
2269- v , succ := parseDigits (input , 2 )
2272+ result := oneOrTwoDigitRegex .FindString (input )
2273+ length := len (result )
2274+
2275+ v , succ := parseDigits (input , length )
22702276 if ! succ || v >= 60 {
22712277 return input , false
22722278 }
22732279 t .minute = uint8 (v )
2274- return input [2 :], true
2280+ return input [length :], true
22752281}
22762282
22772283const time12HourLen = len ("hh:mm:ssAM" )
@@ -2368,6 +2374,9 @@ var oneOrTwoDigitRegex = regexp.MustCompile("^[0-9]{1,2}")
23682374// twoDigitRegex: it was just for two digit number string. Ex: "01" or "12"
23692375var twoDigitRegex = regexp .MustCompile ("^[1-9][0-9]?" )
23702376
2377+ // oneToSixDigitRegex: it was just for [0, 999999]
2378+ var oneToSixDigitRegex = regexp .MustCompile ("^[0-9]{0,6}" )
2379+
23712380// parseTwoNumeric is used for pattens 0..31 0..24 0..60 and so on.
23722381// It returns the parsed int, and remain data after parse.
23732382func parseTwoNumeric (input string ) (int , string ) {
@@ -2427,15 +2436,23 @@ func hour12Numeric(t *MysqlTime, input string, ctx map[string]int) (string, bool
24272436}
24282437
24292438func microSeconds (t * MysqlTime , input string , ctx map [string ]int ) (string , bool ) {
2430- if len (input ) < 6 {
2431- return input , false
2439+ result := oneToSixDigitRegex .FindString (input )
2440+ length := len (result )
2441+ if length == 0 {
2442+ t .microsecond = 0
2443+ return input , true
24322444 }
2433- v , err := strconv .ParseUint (input [:6 ], 10 , 64 )
2434- if err != nil {
2445+
2446+ v , ok := parseDigits (input , length )
2447+
2448+ if ! ok {
24352449 return input , false
24362450 }
2451+ for v > 0 && v * 10 < 1000000 {
2452+ v *= 10
2453+ }
24372454 t .microsecond = uint32 (v )
2438- return input [6 :], true
2455+ return input [length :], true
24392456}
24402457
24412458func yearNumericFourDigits (t * MysqlTime , input string , ctx map [string ]int ) (string , bool ) {
0 commit comments