-
-
Notifications
You must be signed in to change notification settings - Fork 19.1k
Open
Labels
Description
We need multiple custom DateOffset, e.g. so called MonthHalf
.
Until Release 1.1.0 we had a working solution:
import pandas as pd
class MonthHalf(pd.offsets.DateOffset):
"""Date offset repeating on the first date of the month and a day in the middle of the month.
For February the middle day is the 15th, for all other months the 16th."""
_attributes = frozenset(["n"])
_prefix = "MH"
__init__ = pd.offsets.BaseOffset.__init__
@pandas.tseries.offsets.apply_wraps
def apply(self, other: dt.datetime):
month_half_day = self._month_half_day(other.month)
second_month_half = other.day >= month_half_day
n = self.n
new = other
if n < 0:
if not self.onOffset(other):
# Move to the left onto an offset
if second_month_half:
new = new.replace(day=month_half_day)
else:
new = new.replace(day=1)
# One step already happened
n += 1
odd_n = n % 2 == 1
if n > 0:
month_difference = n // 2 + second_month_half * odd_n
elif n == 0:
month_difference = 0
else:
month_difference = n // 2 - second_month_half * (not odd_n)
if month_difference != 0:
new = new + month_difference * pd.offsets.MonthBegin()
month_half_day = self._month_half_day(new.month)
if odd_n:
new_day = 1 if second_month_half else month_half_day
else:
new_day = month_half_day if second_month_half else 1
new = new.replace(day=new_day)
return new
def onOffset(self, date):
return date.day in {1, self._month_half_day(date.month)}
@staticmethod
def _month_half_day(month: int):
return 15 if month == 2 else 16
With release 1.1.0 (and i guess the merge of #34062) code is broken.
E.g. The rollback is not working anymore:
def test_rollback():
date = pd.to_datetime('2018-01-02')
rollback = MonthHalf().rollback(date)
assert rollback == dt.date(2018, 1, 1)
How can i implement such need now?