Skip to content

Commit f093f07

Browse files
authored
REF: de-duplicate month/year rolling in libperiod (#34648)
* REF: implement helpers to de-duplicate year/month rolling * move func to better location
1 parent 43a463d commit f093f07

File tree

1 file changed

+32
-41
lines changed

1 file changed

+32
-41
lines changed

pandas/_libs/tslibs/period.pyx

+32-41
Original file line numberDiff line numberDiff line change
@@ -329,56 +329,34 @@ cdef inline int64_t transform_via_day(int64_t ordinal,
329329
# --------------------------------------------------------------------
330330
# Conversion _to_ Daily Freq
331331

332-
cdef void AtoD_ym(int64_t ordinal, int64_t *year,
333-
int *month, asfreq_info *af_info) nogil:
334-
year[0] = ordinal + 1970
335-
month[0] = 1
336-
337-
if af_info.from_end != 12:
338-
month[0] += af_info.from_end
339-
if month[0] > 12:
340-
# This case is never reached, but is kept for symmetry
341-
# with QtoD_ym
342-
month[0] -= 12
343-
else:
344-
year[0] -= 1
345-
346-
347332
cdef int64_t asfreq_AtoDT(int64_t ordinal, asfreq_info *af_info) nogil:
348333
cdef:
349-
int64_t unix_date, year
350-
int month
334+
int64_t unix_date
335+
npy_datetimestruct dts
351336

352337
ordinal += af_info.is_end
353-
AtoD_ym(ordinal, &year, &month, af_info)
354338

355-
unix_date = unix_date_from_ymd(year, month, 1)
339+
dts.year = ordinal + 1970
340+
dts.month = 1
341+
adjust_dts_for_month(&dts, af_info.from_end)
342+
343+
unix_date = unix_date_from_ymd(dts.year, dts.month, 1)
356344
unix_date -= af_info.is_end
357345
return upsample_daytime(unix_date, af_info)
358346

359347

360-
cdef void QtoD_ym(int64_t ordinal, int *year,
361-
int *month, asfreq_info *af_info) nogil:
362-
year[0] = ordinal // 4 + 1970
363-
month[0] = (ordinal % 4) * 3 + 1
364-
365-
if af_info.from_end != 12:
366-
month[0] += af_info.from_end
367-
if month[0] > 12:
368-
month[0] -= 12
369-
else:
370-
year[0] -= 1
371-
372-
373348
cdef int64_t asfreq_QtoDT(int64_t ordinal, asfreq_info *af_info) nogil:
374349
cdef:
375350
int64_t unix_date
376-
int year, month
351+
npy_datetimestruct dts
377352

378353
ordinal += af_info.is_end
379-
QtoD_ym(ordinal, &year, &month, af_info)
380354

381-
unix_date = unix_date_from_ymd(year, month, 1)
355+
dts.year = ordinal // 4 + 1970
356+
dts.month = (ordinal % 4) * 3 + 1
357+
adjust_dts_for_month(&dts, af_info.from_end)
358+
359+
unix_date = unix_date_from_ymd(dts.year, dts.month, 1)
382360
unix_date -= af_info.is_end
383361
return upsample_daytime(unix_date, af_info)
384362

@@ -486,12 +464,7 @@ cdef int DtoQ_yq(int64_t ordinal, asfreq_info *af_info, npy_datetimestruct* dts)
486464
int quarter
487465

488466
pandas_datetime_to_datetimestruct(ordinal, NPY_FR_D, dts)
489-
if af_info.to_end != 12:
490-
dts.month -= af_info.to_end
491-
if dts.month <= 0:
492-
dts.month += 12
493-
else:
494-
dts.year += 1
467+
adjust_dts_for_qtr(dts, af_info.to_end)
495468

496469
quarter = month_to_quarter(dts.month)
497470
return quarter
@@ -712,6 +685,24 @@ cdef inline int get_freq_group_index(int freq) nogil:
712685
return freq // 1000
713686

714687

688+
cdef void adjust_dts_for_month(npy_datetimestruct* dts, int from_end) nogil:
689+
if from_end != 12:
690+
dts.month += from_end
691+
if dts.month > 12:
692+
dts.month -= 12
693+
else:
694+
dts.year -= 1
695+
696+
697+
cdef void adjust_dts_for_qtr(npy_datetimestruct* dts, int to_end) nogil:
698+
if to_end != 12:
699+
dts.month -= to_end
700+
if dts.month <= 0:
701+
dts.month += 12
702+
else:
703+
dts.year += 1
704+
705+
715706
# Find the unix_date (days elapsed since datetime(1970, 1, 1)
716707
# for the given year/month/day.
717708
# Assumes GREGORIAN_CALENDAR */

0 commit comments

Comments
 (0)