WeekOfMonth vs LastWeekOfMonth inconsistency (original) (raw)

https://github.com/pandas-dev/pandas/blob/master/pandas/tseries/offsets.py#L1496

WeekOfMonth and LastWeekOfMonth have small differences in how they construct getOffsetOfMonth and then in what they do with it. It looks fishy. Any idea why these are done differently? If there's not a reason for it, I'd like to align+merge them.

class WeekOfMonth(DateOffset):
    [...]
    @apply_wraps
    def apply(self, other):
        base = other
        offsetOfMonth = self.getOffsetOfMonth(other)

        months = self.n
        if months > 0 and offsetOfMonth > other:
            months -= 1
        elif months <= 0 and offsetOfMonth < other:
            months += 1

        other = self.getOffsetOfMonth(shift_month(other, months, 'start'))
        other = datetime(other.year, other.month, other.day, base.hour,
                         base.minute, base.second, base.microsecond)
        return other

    def getOffsetOfMonth(self, dt):
        w = Week(weekday=self.weekday)
        d = datetime(dt.year, dt.month, 1, tzinfo=dt.tzinfo)
        # TODO: Is this DST-safe?
        d = w.rollforward(d)
        return d + timedelta(weeks=self.week)


    def onOffset(self, dt):
        if self.normalize and not _is_normalized(dt):
            return False
        d = datetime(dt.year, dt.month, dt.day, tzinfo=dt.tzinfo)
        return d == self.getOffsetOfMonth(dt)

class LastWeekOfMonth(DateOffset):
    [...]
    @apply_wraps
    def apply(self, other):
        offsetOfMonth = self.getOffsetOfMonth(other)

        months = self.n
        if months > 0 and offsetOfMonth > other:
            months -= 1
        elif months <= 0 and offsetOfMonth < other:
            months += 1

        return self.getOffsetOfMonth(shift_month(other, months, 'start'))

    def getOffsetOfMonth(self, dt):
        m = MonthEnd()
        d = datetime(dt.year, dt.month, 1, dt.hour, dt.minute,
                     dt.second, dt.microsecond, tzinfo=dt.tzinfo)
        eom = m.rollforward(d)
        # TODO: Is this DST-safe?
        w = Week(weekday=self.weekday)
        return w.rollback(eom)

    def onOffset(self, dt):
        if self.normalize and not _is_normalized(dt):
            return False
        return dt == self.getOffsetOfMonth(dt)