@@ -566,6 +566,27 @@ bool is_valid_time(const int hours, const int minutes, const int seconds) {
566566 seconds < 60 ;
567567}
568568
569+ // Normalize sub-seconds value to milliseconds precision (3 digits).
570+ // Truncates if more than 3 digits are provided, pads with zeros if fewer than 3 digits
571+ FORCE_INLINE
572+ int32_t normalize_subseconds_to_millis (int32_t subseconds, int32_t num_digits) {
573+ if (num_digits <= 0 || num_digits == 3 ) {
574+ // No need to adjust
575+ return subseconds;
576+ }
577+ // Calculate the power of 10 adjustment needed
578+ int32_t digit_diff = num_digits - 3 ;
579+ while (digit_diff > 0 ) {
580+ subseconds /= 10 ;
581+ digit_diff--;
582+ }
583+ while (digit_diff < 0 ) {
584+ subseconds *= 10 ;
585+ digit_diff++;
586+ }
587+ return subseconds;
588+ }
589+
569590// MONTHS_BETWEEN returns number of months between dates date1 and date2.
570591// If date1 is later than date2, then the result is positive.
571592// If date1 is earlier than date2, then the result is negative.
@@ -746,18 +767,8 @@ gdv_timestamp castTIMESTAMP_utf8(int64_t context, const char* input, gdv_int32 l
746767 }
747768
748769 // adjust the milliseconds
749- if (sub_seconds_len > 0 ) {
750- // Truncate to 3 digits (milliseconds precision) if more digits are provided
751- while (sub_seconds_len > 3 ) {
752- ts_fields[TimeFields::kSubSeconds ] /= 10 ;
753- sub_seconds_len--;
754- }
755- // Pad with zeros if less than 3 digits
756- while (sub_seconds_len < 3 ) {
757- ts_fields[TimeFields::kSubSeconds ] *= 10 ;
758- sub_seconds_len++;
759- }
760- }
770+ ts_fields[TimeFields::kSubSeconds ] =
771+ normalize_subseconds_to_millis (ts_fields[TimeFields::kSubSeconds ], sub_seconds_len);
761772 // handle timezone
762773 if (encountered_zone) {
763774 int err = 0 ;
@@ -867,18 +878,8 @@ gdv_time32 castTIME_utf8(int64_t context, const char* input, int32_t length) {
867878 }
868879
869880 // adjust the milliseconds
870- if (sub_seconds_len > 0 ) {
871- // Truncate to 3 digits (milliseconds precision) if more digits are provided
872- while (sub_seconds_len > 3 ) {
873- time_fields[TimeFields::kSubSeconds - TimeFields::kHours ] /= 10 ;
874- sub_seconds_len--;
875- }
876- // Pad with zeros if less than 3 digits
877- while (sub_seconds_len < 3 ) {
878- time_fields[TimeFields::kSubSeconds - TimeFields::kHours ] *= 10 ;
879- sub_seconds_len++;
880- }
881- }
881+ time_fields[TimeFields::kSubSeconds - TimeFields::kHours ] = normalize_subseconds_to_millis (
882+ time_fields[TimeFields::kSubSeconds - TimeFields::kHours ], sub_seconds_len);
882883
883884 int32_t input_hours = time_fields[TimeFields::kHours - TimeFields::kHours ];
884885 int32_t input_minutes = time_fields[TimeFields::kMinutes - TimeFields::kHours ];
0 commit comments