@@ -294,9 +294,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
294
294
case MYSQL_TYPE_DATETIME : { /* DATETIME field */
295
295
int tokens ;
296
296
unsigned int year = 0 , month = 0 , day = 0 , hour = 0 , min = 0 , sec = 0 , msec = 0 ;
297
+ char msec_char [7 ] = {'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'\0' };
297
298
uint64_t seconds ;
298
299
299
- tokens = sscanf (row [i ], "%4u-%2u-%2u %2u:%2u:%2u.%6u " , & year , & month , & day , & hour , & min , & sec , & msec );
300
+ tokens = sscanf (row [i ], "%4u-%2u-%2u %2u:%2u:%2u.%6s " , & year , & month , & day , & hour , & min , & sec , msec_char );
300
301
if (tokens < 6 ) { /* msec might be empty */
301
302
val = Qnil ;
302
303
break ;
@@ -324,7 +325,19 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
324
325
val = rb_funcall (val , intern_new_offset , 1 , opt_utc_offset );
325
326
}
326
327
}
327
- } else { /* use Time, supports microseconds */
328
+ } else {
329
+ /* microseconds can be up to 6 digits. Fewer digits must be interpreted from
330
+ * the left because the microseconds are to the right of the decimal point.
331
+ */
332
+ if (tokens == 7 ) {
333
+ int i ;
334
+ for (i = 0 ; i < 6 ; ++ i ) {
335
+ if (msec_char [i ] == '\0' ) {
336
+ msec_char [i ] = '0' ;
337
+ }
338
+ }
339
+ msec = (unsigned int )strtoul (msec_char , NULL , 10 );
340
+ }
328
341
val = rb_funcall (rb_cTime , db_timezone , 7 , UINT2NUM (year ), UINT2NUM (month ), UINT2NUM (day ), UINT2NUM (hour ), UINT2NUM (min ), UINT2NUM (sec ), UINT2NUM (msec ));
329
342
if (!NIL_P (app_timezone )) {
330
343
if (app_timezone == intern_local ) {
0 commit comments