@@ -812,6 +812,45 @@ cdef int64_t get_period_ordinal(npy_datetimestruct *dts, int freq) noexcept nogi
812812 unit = freq_group_code_to_npy_unit(freq)
813813 return npy_datetimestruct_to_datetime(unit, dts)
814814
815+ cdef int64_t _period_ordinal_safe(npy_datetimestruct * dts, int freq) except ? - 1 :
816+ """
817+ Safe variant of get_period_ordinal used by the Python API (period_ordinal).
818+
819+ It mirrors get_period_ordinal's logic but is allowed to raise Python
820+ exceptions instead of leaking OverflowError from numpy's datetime code.
821+ """
822+ cdef:
823+ int64_t unix_date
824+ int freq_group, fmonth
825+ NPY_DATETIMEUNIT unit
826+
827+ freq_group = get_freq_group(freq)
828+
829+ try :
830+ if freq_group == FR_ANN:
831+ fmonth = get_anchor_month(freq, freq_group)
832+ return dts_to_year_ordinal(dts, fmonth)
833+
834+ elif freq_group == FR_QTR:
835+ fmonth = get_anchor_month(freq, freq_group)
836+ return dts_to_qtr_ordinal(dts, fmonth)
837+
838+ elif freq_group == FR_WK:
839+ unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)
840+ return unix_date_to_week(unix_date, freq - FR_WK)
841+
842+ elif freq == FR_BUS:
843+ unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)
844+ return DtoB(dts, 0 , unix_date)
845+
846+ unit = freq_group_code_to_npy_unit(freq)
847+ return npy_datetimestruct_to_datetime(unit, dts)
848+
849+ except OverflowError as err:
850+ # Translate low-level overflow into a user-facing OutOfBoundsDatetime.
851+ fmt = dts_to_iso_string(dts)
852+ raise OutOfBoundsDatetime(f" Out of bounds datetime for Period with freq {freq}: {fmt}" ) from err
853+
815854
816855cdef void get_date_info(int64_t ordinal,
817856 int freq, npy_datetimestruct * dts) noexcept nogil:
@@ -1150,7 +1189,8 @@ cpdef int64_t period_ordinal(int y, int m, int d, int h, int min,
11501189 dts.sec = s
11511190 dts.us = us
11521191 dts.ps = ps
1153- return get_period_ordinal(& dts, freq)
1192+ # return get_period_ordinal(&dts, freq)
1193+ return _period_ordinal_safe(& dts, freq)
11541194
11551195
11561196cdef int64_t period_ordinal_to_dt64(int64_t ordinal, int freq) except ? - 1 :
0 commit comments