Skip to content

Commit 0f2db73

Browse files
authored
REF: de-duplication in libperiod (#38985)
1 parent d1a5594 commit 0f2db73

File tree

1 file changed

+43
-26
lines changed

1 file changed

+43
-26
lines changed

pandas/_libs/tslibs/period.pyx

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -357,18 +357,15 @@ cdef int64_t asfreq_QtoDT(int64_t ordinal, asfreq_info *af_info) nogil:
357357
return upsample_daytime(unix_date, af_info)
358358

359359

360-
cdef void MtoD_ym(int64_t ordinal, int *year, int *month) nogil:
361-
year[0] = ordinal // 12 + 1970
362-
month[0] = ordinal % 12 + 1
363-
364-
365360
cdef int64_t asfreq_MtoDT(int64_t ordinal, asfreq_info *af_info) nogil:
366361
cdef:
367362
int64_t unix_date
368363
int year, month
369364

370365
ordinal += af_info.is_end
371-
MtoD_ym(ordinal, &year, &month)
366+
367+
year = ordinal // 12 + 1970
368+
month = ordinal % 12 + 1
372369

373370
unix_date = unix_date_from_ymd(year, month, 1)
374371
unix_date -= af_info.is_end
@@ -449,10 +446,7 @@ cdef int64_t asfreq_DTtoA(int64_t ordinal, asfreq_info *af_info) nogil:
449446

450447
ordinal = downsample_daytime(ordinal, af_info)
451448
pandas_datetime_to_datetimestruct(ordinal, NPY_FR_D, &dts)
452-
if dts.month > af_info.to_end:
453-
return <int64_t>(dts.year + 1 - 1970)
454-
else:
455-
return <int64_t>(dts.year - 1970)
449+
return dts_to_year_ordinal(&dts, af_info.to_end)
456450

457451

458452
cdef int DtoQ_yq(int64_t ordinal, asfreq_info *af_info, npy_datetimestruct* dts) nogil:
@@ -483,7 +477,7 @@ cdef int64_t asfreq_DTtoM(int64_t ordinal, asfreq_info *af_info) nogil:
483477

484478
ordinal = downsample_daytime(ordinal, af_info)
485479
pandas_datetime_to_datetimestruct(ordinal, NPY_FR_D, &dts)
486-
return <int64_t>((dts.year - 1970) * 12 + dts.month - 1)
480+
return dts_to_month_ordinal(&dts)
487481

488482

489483
cdef int64_t asfreq_DTtoW(int64_t ordinal, asfreq_info *af_info) nogil:
@@ -716,6 +710,40 @@ cdef int64_t unix_date_from_ymd(int year, int month, int day) nogil:
716710
return unix_date
717711

718712

713+
cdef inline int64_t dts_to_month_ordinal(npy_datetimestruct* dts) nogil:
714+
# AKA: use npy_datetimestruct_to_datetime(NPY_FR_M, &dts)
715+
return <int64_t>((dts.year - 1970) * 12 + dts.month - 1)
716+
717+
718+
cdef inline int64_t dts_to_year_ordinal(npy_datetimestruct *dts, int to_end) nogil:
719+
cdef:
720+
int64_t result
721+
722+
result = npy_datetimestruct_to_datetime(NPY_DATETIMEUNIT.NPY_FR_Y, dts)
723+
if dts.month > to_end:
724+
return result + 1
725+
else:
726+
return result
727+
728+
729+
cdef inline int64_t dts_to_qtr_ordinal(npy_datetimestruct* dts, int to_end) nogil:
730+
cdef:
731+
int quarter
732+
733+
adjust_dts_for_qtr(dts, to_end)
734+
quarter = month_to_quarter(dts.month)
735+
return <int64_t>((dts.year - 1970) * 4 + quarter - 1)
736+
737+
738+
cdef inline int get_anchor_month(int freq, int freq_group) nogil:
739+
cdef:
740+
int fmonth
741+
fmonth = freq - freq_group
742+
if fmonth == 0:
743+
fmonth = 12
744+
return fmonth
745+
746+
719747
# specifically _dont_ use cdvision or else ordinals near -1 are assigned to
720748
# incorrect dates GH#19643
721749
@cython.cdivision(False)
@@ -740,23 +768,12 @@ cdef int64_t get_period_ordinal(npy_datetimestruct *dts, int freq) nogil:
740768
freq_group = get_freq_group(freq)
741769

742770
if freq_group == FR_ANN:
743-
fmonth = freq - FR_ANN
744-
if fmonth == 0:
745-
fmonth = 12
746-
747-
mdiff = dts.month - fmonth
748-
if mdiff <= 0:
749-
return dts.year - 1970
750-
else:
751-
return dts.year - 1970 + 1
771+
fmonth = get_anchor_month(freq, freq_group)
772+
return dts_to_year_ordinal(dts, fmonth)
752773

753774
elif freq_group == FR_QTR:
754-
fmonth = freq - FR_QTR
755-
if fmonth == 0:
756-
fmonth = 12
757-
758-
mdiff = dts.month - fmonth + 12
759-
return (dts.year - 1970) * 4 + (mdiff - 1) // 3
775+
fmonth = get_anchor_month(freq, freq_group)
776+
return dts_to_qtr_ordinal(dts, fmonth)
760777

761778
elif freq_group == FR_WK:
762779
unix_date = npy_datetimestruct_to_datetime(NPY_FR_D, dts)

0 commit comments

Comments
 (0)