Skip to content

Commit c482b57

Browse files
authored
inline get_day_of_month (#34772)
1 parent 28be10b commit c482b57

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

pandas/_libs/tslibs/offsets.pyx

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3757,16 +3757,22 @@ cdef shift_quarters(
37573757
n = quarters
37583758

37593759
months_since = (dts.month - q1start_month) % modby
3760+
compare_day = get_day_of_month(&dts, day_opt)
37603761

37613762
# offset semantics - if on the anchor point and going backwards
37623763
# shift to next
37633764
if n <= 0 and (months_since != 0 or
3764-
(months_since == 0 and dts.day > 1)):
3765+
(months_since == 0 and dts.day > compare_day)):
3766+
# make sure to roll forward, so negate
37653767
n += 1
3768+
elif n > 0 and (months_since == 0 and dts.day < compare_day):
3769+
# pretend to roll back if on same month but
3770+
# before compare_day
3771+
n -= 1
37663772

37673773
dts.year = year_add_months(dts, modby * n - months_since)
37683774
dts.month = month_add_months(dts, modby * n - months_since)
3769-
dts.day = 1
3775+
dts.day = get_day_of_month(&dts, day_opt)
37703776

37713777
out[i] = dtstruct_to_dt64(&dts)
37723778

@@ -3781,21 +3787,20 @@ cdef shift_quarters(
37813787
n = quarters
37823788

37833789
months_since = (dts.month - q1start_month) % modby
3790+
compare_day = get_day_of_month(&dts, day_opt)
37843791

3785-
if n <= 0 and months_since != 0:
3786-
# The general case of this condition would be
3787-
# `months_since != 0 or (months_since == 0 and
3788-
# dts.day > get_days_in_month(dts.year, dts.month))`
3789-
# but the get_days_in_month inequality would never hold.
3792+
if n <= 0 and (months_since != 0 or
3793+
(months_since == 0 and dts.day > compare_day)):
3794+
# make sure to roll forward, so negate
37903795
n += 1
3791-
elif n > 0 and (months_since == 0 and
3792-
dts.day < get_days_in_month(dts.year,
3793-
dts.month)):
3796+
elif n > 0 and (months_since == 0 and dts.day < compare_day):
3797+
# pretend to roll back if on same month but
3798+
# before compare_day
37943799
n -= 1
37953800

37963801
dts.year = year_add_months(dts, modby * n - months_since)
37973802
dts.month = month_add_months(dts, modby * n - months_since)
3798-
dts.day = get_days_in_month(dts.year, dts.month)
3803+
dts.day = get_day_of_month(&dts, day_opt)
37993804

38003805
out[i] = dtstruct_to_dt64(&dts)
38013806

@@ -3812,7 +3817,7 @@ cdef shift_quarters(
38123817
months_since = (dts.month - q1start_month) % modby
38133818
# compare_day is only relevant for comparison in the case
38143819
# where months_since == 0.
3815-
compare_day = get_firstbday(dts.year, dts.month)
3820+
compare_day = get_day_of_month(&dts, day_opt)
38163821

38173822
if n <= 0 and (months_since != 0 or
38183823
(months_since == 0 and dts.day > compare_day)):
@@ -3826,7 +3831,7 @@ cdef shift_quarters(
38263831
dts.year = year_add_months(dts, modby * n - months_since)
38273832
dts.month = month_add_months(dts, modby * n - months_since)
38283833

3829-
dts.day = get_firstbday(dts.year, dts.month)
3834+
dts.day = get_day_of_month(&dts, day_opt)
38303835

38313836
out[i] = dtstruct_to_dt64(&dts)
38323837

@@ -3843,7 +3848,7 @@ cdef shift_quarters(
38433848
months_since = (dts.month - q1start_month) % modby
38443849
# compare_day is only relevant for comparison in the case
38453850
# where months_since == 0.
3846-
compare_day = get_lastbday(dts.year, dts.month)
3851+
compare_day = get_day_of_month(&dts, day_opt)
38473852

38483853
if n <= 0 and (months_since != 0 or
38493854
(months_since == 0 and dts.day > compare_day)):
@@ -3857,7 +3862,7 @@ cdef shift_quarters(
38573862
dts.year = year_add_months(dts, modby * n - months_since)
38583863
dts.month = month_add_months(dts, modby * n - months_since)
38593864

3860-
dts.day = get_lastbday(dts.year, dts.month)
3865+
dts.day = get_day_of_month(&dts, day_opt)
38613866

38623867
out[i] = dtstruct_to_dt64(&dts)
38633868

@@ -3909,7 +3914,7 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39093914

39103915
dt64_to_dtstruct(dtindex[i], &dts)
39113916
months_to_roll = months
3912-
compare_day = 1
3917+
compare_day = get_day_of_month(&dts, day_opt)
39133918

39143919
# offset semantics - if on the anchor point and going backwards
39153920
# shift to next
@@ -3918,7 +3923,7 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39183923

39193924
dts.year = year_add_months(dts, months_to_roll)
39203925
dts.month = month_add_months(dts, months_to_roll)
3921-
dts.day = 1
3926+
dts.day = get_day_of_month(&dts, day_opt)
39223927

39233928
out[i] = dtstruct_to_dt64(&dts)
39243929
elif day_opt == "end":
@@ -3930,7 +3935,7 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39303935

39313936
dt64_to_dtstruct(dtindex[i], &dts)
39323937
months_to_roll = months
3933-
compare_day = get_days_in_month(dts.year, dts.month)
3938+
compare_day = get_day_of_month(&dts, day_opt)
39343939

39353940
# similar semantics - when adding shift forward by one
39363941
# month if already at an end of month
@@ -3940,7 +3945,7 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39403945
dts.year = year_add_months(dts, months_to_roll)
39413946
dts.month = month_add_months(dts, months_to_roll)
39423947

3943-
dts.day = get_days_in_month(dts.year, dts.month)
3948+
dts.day = get_day_of_month(&dts, day_opt)
39443949
out[i] = dtstruct_to_dt64(&dts)
39453950

39463951
elif day_opt == "business_start":
@@ -3952,15 +3957,15 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39523957

39533958
dt64_to_dtstruct(dtindex[i], &dts)
39543959
months_to_roll = months
3955-
compare_day = get_firstbday(dts.year, dts.month)
3960+
compare_day = get_day_of_month(&dts, day_opt)
39563961

39573962
months_to_roll = roll_convention(dts.day, months_to_roll,
39583963
compare_day)
39593964

39603965
dts.year = year_add_months(dts, months_to_roll)
39613966
dts.month = month_add_months(dts, months_to_roll)
39623967

3963-
dts.day = get_firstbday(dts.year, dts.month)
3968+
dts.day = get_day_of_month(&dts, day_opt)
39643969
out[i] = dtstruct_to_dt64(&dts)
39653970

39663971
elif day_opt == "business_end":
@@ -3972,15 +3977,15 @@ def shift_months(const int64_t[:] dtindex, int months, object day_opt=None):
39723977

39733978
dt64_to_dtstruct(dtindex[i], &dts)
39743979
months_to_roll = months
3975-
compare_day = get_lastbday(dts.year, dts.month)
3980+
compare_day = get_day_of_month(&dts, day_opt)
39763981

39773982
months_to_roll = roll_convention(dts.day, months_to_roll,
39783983
compare_day)
39793984

39803985
dts.year = year_add_months(dts, months_to_roll)
39813986
dts.month = month_add_months(dts, months_to_roll)
39823987

3983-
dts.day = get_lastbday(dts.year, dts.month)
3988+
dts.day = get_day_of_month(&dts, day_opt)
39843989
out[i] = dtstruct_to_dt64(&dts)
39853990

39863991
else:
@@ -4051,7 +4056,7 @@ def shift_month(stamp: datetime, months: int,
40514056
return stamp.replace(year=year, month=month, day=day)
40524057

40534058

4054-
cdef int get_day_of_month(npy_datetimestruct* dts, day_opt) nogil except? -1:
4059+
cdef inline int get_day_of_month(npy_datetimestruct* dts, day_opt) nogil except? -1:
40554060
"""
40564061
Find the day in `other`'s month that satisfies a DateOffset's is_on_offset
40574062
policy, as described by the `day_opt` argument.

0 commit comments

Comments
 (0)