@@ -408,33 +408,54 @@ static VALUE rb_mysql_result_stmt_fetch_row(VALUE self, ID db_timezone, ID app_t
408
408
val = rb_float_new ((double )(* ((double * )result_buffer -> buffer )));
409
409
break ;
410
410
case MYSQL_TYPE_DATE : // MYSQL_TIME
411
+ case MYSQL_TYPE_NEWDATE : // MYSQL_TIME
411
412
ts = (MYSQL_TIME * )result_buffer -> buffer ;
412
413
val = rb_funcall (cDate , rb_intern ("new" ), 3 , INT2NUM (ts -> year ), INT2NUM (ts -> month ), INT2NUM (ts -> day ));
413
414
break ;
414
415
case MYSQL_TYPE_TIME : // MYSQL_TIME
415
416
ts = (MYSQL_TIME * )result_buffer -> buffer ;
416
- val = rb_funcall (rb_cTime ,
417
- rb_intern ( "mktime" ), 6 ,
418
- opt_time_year ,
419
- opt_time_month ,
420
- opt_time_month ,
421
- UINT2NUM ( ts -> hour ),
422
- UINT2NUM ( ts -> minute ),
423
- UINT2NUM ( ts -> second ));
417
+ val = rb_funcall (rb_cTime , db_timezone , 6 , opt_time_year , opt_time_month , opt_time_month , UINT2NUM ( ts -> hour ), UINT2NUM ( ts -> minute ), UINT2NUM ( ts -> second ));
418
+ if (! NIL_P ( app_timezone )) {
419
+ if ( app_timezone == intern_local ) {
420
+ val = rb_funcall ( val , intern_localtime , 0 );
421
+ } else { // utc
422
+ val = rb_funcall ( val , intern_utc , 0 );
423
+ }
424
+ }
424
425
break ;
425
- case MYSQL_TYPE_NEWDATE : // MYSQL_TIME
426
426
case MYSQL_TYPE_DATETIME : // MYSQL_TIME
427
- case MYSQL_TYPE_TIMESTAMP : // MYSQL_TIME
427
+ case MYSQL_TYPE_TIMESTAMP : { // MYSQL_TIME
428
+ uint64_t seconds ;
429
+
428
430
ts = (MYSQL_TIME * )result_buffer -> buffer ;
429
- val = rb_funcall (rb_cTime ,
430
- rb_intern ("mktime" ), 6 ,
431
- UINT2NUM (ts -> year ),
432
- UINT2NUM (ts -> month ),
433
- UINT2NUM (ts -> day ),
434
- UINT2NUM (ts -> hour ),
435
- UINT2NUM (ts -> minute ),
436
- UINT2NUM (ts -> second ));
431
+ seconds = (ts -> year * 31557600ULL ) + (ts -> month * 2592000ULL ) + (ts -> day * 86400ULL ) + (ts -> hour * 3600ULL ) + (ts -> minute * 60ULL ) + ts -> second ;
432
+
433
+ if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME ) { // use DateTime instead
434
+ VALUE offset = INT2NUM (0 );
435
+ if (db_timezone == intern_local ) {
436
+ offset = rb_funcall (cMysql2Client , intern_local_offset , 0 );
437
+ }
438
+ val = rb_funcall (cDateTime , intern_civil , 7 , UINT2NUM (ts -> year ), UINT2NUM (ts -> month ), UINT2NUM (ts -> day ), UINT2NUM (ts -> hour ), UINT2NUM (ts -> minute ), UINT2NUM (ts -> second ), offset );
439
+ if (!NIL_P (app_timezone )) {
440
+ if (app_timezone == intern_local ) {
441
+ offset = rb_funcall (cMysql2Client , intern_local_offset , 0 );
442
+ val = rb_funcall (val , intern_new_offset , 1 , offset );
443
+ } else { // utc
444
+ val = rb_funcall (val , intern_new_offset , 1 , opt_utc_offset );
445
+ }
446
+ }
447
+ } else {
448
+ val = rb_funcall (rb_cTime , db_timezone , 6 , UINT2NUM (ts -> year ), UINT2NUM (ts -> month ), UINT2NUM (ts -> day ), UINT2NUM (ts -> hour ), UINT2NUM (ts -> minute ), UINT2NUM (ts -> second ));
449
+ if (!NIL_P (app_timezone )) {
450
+ if (app_timezone == intern_local ) {
451
+ val = rb_funcall (val , intern_localtime , 0 );
452
+ } else { // utc
453
+ val = rb_funcall (val , intern_utc , 0 );
454
+ }
455
+ }
456
+ }
437
457
break ;
458
+ }
438
459
case MYSQL_TYPE_DECIMAL : // char[]
439
460
case MYSQL_TYPE_NEWDECIMAL : // char[]
440
461
val = rb_funcall (cBigDecimal , rb_intern ("new" ), 1 , rb_str_new (result_buffer -> buffer , * (result_buffer -> length )));
0 commit comments