""" Tests for offset.Week, offset.WeekofMonth and offset.LastWeekofMonth """ from datetime import ( datetime, timedelta, ) import pytest from pandas._libs.tslibs import Timestamp from pandas._libs.tslibs.offsets import ( LastWeekOfMonth, Week, WeekOfMonth, ) from pandas.tests.tseries.offsets.common import ( Base, WeekDay, assert_is_on_offset, assert_offset_equal, ) class TestWeek(Base): _offset = Week d = Timestamp(datetime(2008, 1, 2)) offset1 = _offset() offset2 = _offset(2) def test_repr(self): assert repr(Week(weekday=0)) == "" assert repr(Week(n=-1, weekday=0)) == "<-1 * Week: weekday=0>" assert repr(Week(n=-2, weekday=0)) == "<-2 * Weeks: weekday=0>" def test_corner(self): with pytest.raises(ValueError, match="Day must be"): Week(weekday=7) with pytest.raises(ValueError, match="Day must be"): Week(weekday=-1) def test_is_anchored(self): assert Week(weekday=0).is_anchored() assert not Week().is_anchored() assert not Week(2, weekday=2).is_anchored() assert not Week(2).is_anchored() offset_cases = [] # not business week offset_cases.append( ( Week(), { datetime(2008, 1, 1): datetime(2008, 1, 8), datetime(2008, 1, 4): datetime(2008, 1, 11), datetime(2008, 1, 5): datetime(2008, 1, 12), datetime(2008, 1, 6): datetime(2008, 1, 13), datetime(2008, 1, 7): datetime(2008, 1, 14), }, ) ) # Mon offset_cases.append( ( Week(weekday=0), { datetime(2007, 12, 31): datetime(2008, 1, 7), datetime(2008, 1, 4): datetime(2008, 1, 7), datetime(2008, 1, 5): datetime(2008, 1, 7), datetime(2008, 1, 6): datetime(2008, 1, 7), datetime(2008, 1, 7): datetime(2008, 1, 14), }, ) ) # n=0 -> roll forward. Mon offset_cases.append( ( Week(0, weekday=0), { datetime(2007, 12, 31): datetime(2007, 12, 31), datetime(2008, 1, 4): datetime(2008, 1, 7), datetime(2008, 1, 5): datetime(2008, 1, 7), datetime(2008, 1, 6): datetime(2008, 1, 7), datetime(2008, 1, 7): datetime(2008, 1, 7), }, ) ) # n=0 -> roll forward. Mon offset_cases.append( ( Week(-2, weekday=1), { datetime(2010, 4, 6): datetime(2010, 3, 23), datetime(2010, 4, 8): datetime(2010, 3, 30), datetime(2010, 4, 5): datetime(2010, 3, 23), }, ) ) @pytest.mark.parametrize("case", offset_cases) def test_offset(self, case): offset, cases = case for base, expected in cases.items(): assert_offset_equal(offset, base, expected) @pytest.mark.parametrize("weekday", range(7)) def test_is_on_offset(self, weekday): offset = Week(weekday=weekday) for day in range(1, 8): date = datetime(2008, 1, day) if day % 7 == weekday: expected = True else: expected = False assert_is_on_offset(offset, date, expected) class TestWeekOfMonth(Base): _offset = WeekOfMonth offset1 = _offset() offset2 = _offset(2) def test_constructor(self): with pytest.raises(ValueError, match="^Week"): WeekOfMonth(n=1, week=4, weekday=0) with pytest.raises(ValueError, match="^Week"): WeekOfMonth(n=1, week=-1, weekday=0) with pytest.raises(ValueError, match="^Day"): WeekOfMonth(n=1, week=0, weekday=-1) with pytest.raises(ValueError, match="^Day"): WeekOfMonth(n=1, week=0, weekday=-7) def test_repr(self): assert ( repr(WeekOfMonth(weekday=1, week=2)) == "" ) def test_offset(self): date1 = datetime(2011, 1, 4) # 1st Tuesday of Month date2 = datetime(2011, 1, 11) # 2nd Tuesday of Month date3 = datetime(2011, 1, 18) # 3rd Tuesday of Month date4 = datetime(2011, 1, 25) # 4th Tuesday of Month # see for loop for structure test_cases = [ (-2, 2, 1, date1, datetime(2010, 11, 16)), (-2, 2, 1, date2, datetime(2010, 11, 16)), (-2, 2, 1, date3, datetime(2010, 11, 16)), (-2, 2, 1, date4, datetime(2010, 12, 21)), (-1, 2, 1, date1, datetime(2010, 12, 21)), (-1, 2, 1, date2, datetime(2010, 12, 21)), (-1, 2, 1, date3, datetime(2010, 12, 21)), (-1, 2, 1, date4, datetime(2011, 1, 18)), (0, 0, 1, date1, datetime(2011, 1, 4)), (0, 0, 1, date2, datetime(2011, 2, 1)), (0, 0, 1, date3, datetime(2011, 2, 1)), (0, 0, 1, date4, datetime(2011, 2, 1)), (0, 1, 1, date1, datetime(2011, 1, 11)), (0, 1, 1, date2, datetime(2011, 1, 11)), (0, 1, 1, date3, datetime(2011, 2, 8)), (0, 1, 1, date4, datetime(2011, 2, 8)), (0, 0, 1, date1, datetime(2011, 1, 4)), (0, 1, 1, date2, datetime(2011, 1, 11)), (0, 2, 1, date3, datetime(2011, 1, 18)), (0, 3, 1, date4, datetime(2011, 1, 25)), (1, 0, 0, date1, datetime(2011, 2, 7)), (1, 0, 0, date2, datetime(2011, 2, 7)), (1, 0, 0, date3, datetime(2011, 2, 7)), (1, 0, 0, date4, datetime(2011, 2, 7)), (1, 0, 1, date1, datetime(2011, 2, 1)), (1, 0, 1, date2, datetime(2011, 2, 1)), (1, 0, 1, date3, datetime(2011, 2, 1)), (1, 0, 1, date4, datetime(2011, 2, 1)), (1, 0, 2, date1, datetime(2011, 1, 5)), (1, 0, 2, date2, datetime(2011, 2, 2)), (1, 0, 2, date3, datetime(2011, 2, 2)), (1, 0, 2, date4, datetime(2011, 2, 2)), (1, 2, 1, date1, datetime(2011, 1, 18)), (1, 2, 1, date2, datetime(2011, 1, 18)), (1, 2, 1, date3, datetime(2011, 2, 15)), (1, 2, 1, date4, datetime(2011, 2, 15)), (2, 2, 1, date1, datetime(2011, 2, 15)), (2, 2, 1, date2, datetime(2011, 2, 15)), (2, 2, 1, date3, datetime(2011, 3, 15)), (2, 2, 1, date4, datetime(2011, 3, 15)), ] for n, week, weekday, dt, expected in test_cases: offset = WeekOfMonth(n, week=week, weekday=weekday) assert_offset_equal(offset, dt, expected) # try subtracting result = datetime(2011, 2, 1) - WeekOfMonth(week=1, weekday=2) assert result == datetime(2011, 1, 12) result = datetime(2011, 2, 3) - WeekOfMonth(week=0, weekday=2) assert result == datetime(2011, 2, 2) on_offset_cases = [ (0, 0, datetime(2011, 2, 7), True), (0, 0, datetime(2011, 2, 6), False), (0, 0, datetime(2011, 2, 14), False), (1, 0, datetime(2011, 2, 14), True), (0, 1, datetime(2011, 2, 1), True), (0, 1, datetime(2011, 2, 8), False), ] @pytest.mark.parametrize("case", on_offset_cases) def test_is_on_offset(self, case): week, weekday, dt, expected = case offset = WeekOfMonth(week=week, weekday=weekday) assert offset.is_on_offset(dt) == expected class TestLastWeekOfMonth(Base): _offset = LastWeekOfMonth offset1 = _offset() offset2 = _offset(2) def test_constructor(self): with pytest.raises(ValueError, match="^N cannot be 0"): LastWeekOfMonth(n=0, weekday=1) with pytest.raises(ValueError, match="^Day"): LastWeekOfMonth(n=1, weekday=-1) with pytest.raises(ValueError, match="^Day"): LastWeekOfMonth(n=1, weekday=7) def test_offset(self): # Saturday last_sat = datetime(2013, 8, 31) next_sat = datetime(2013, 9, 28) offset_sat = LastWeekOfMonth(n=1, weekday=5) one_day_before = last_sat + timedelta(days=-1) assert one_day_before + offset_sat == last_sat one_day_after = last_sat + timedelta(days=+1) assert one_day_after + offset_sat == next_sat # Test On that day assert last_sat + offset_sat == next_sat # Thursday offset_thur = LastWeekOfMonth(n=1, weekday=3) last_thurs = datetime(2013, 1, 31) next_thurs = datetime(2013, 2, 28) one_day_before = last_thurs + timedelta(days=-1) assert one_day_before + offset_thur == last_thurs one_day_after = last_thurs + timedelta(days=+1) assert one_day_after + offset_thur == next_thurs # Test on that day assert last_thurs + offset_thur == next_thurs three_before = last_thurs + timedelta(days=-3) assert three_before + offset_thur == last_thurs two_after = last_thurs + timedelta(days=+2) assert two_after + offset_thur == next_thurs offset_sunday = LastWeekOfMonth(n=1, weekday=WeekDay.SUN) assert datetime(2013, 7, 31) + offset_sunday == datetime(2013, 8, 25) on_offset_cases = [ (WeekDay.SUN, datetime(2013, 1, 27), True), (WeekDay.SAT, datetime(2013, 3, 30), True), (WeekDay.MON, datetime(2013, 2, 18), False), # Not the last Mon (WeekDay.SUN, datetime(2013, 2, 25), False), # Not a SUN (WeekDay.MON, datetime(2013, 2, 25), True), (WeekDay.SAT, datetime(2013, 11, 30), True), (WeekDay.SAT, datetime(2006, 8, 26), True), (WeekDay.SAT, datetime(2007, 8, 25), True), (WeekDay.SAT, datetime(2008, 8, 30), True), (WeekDay.SAT, datetime(2009, 8, 29), True), (WeekDay.SAT, datetime(2010, 8, 28), True), (WeekDay.SAT, datetime(2011, 8, 27), True), (WeekDay.SAT, datetime(2019, 8, 31), True), ] @pytest.mark.parametrize("case", on_offset_cases) def test_is_on_offset(self, case): weekday, dt, expected = case offset = LastWeekOfMonth(weekday=weekday) assert offset.is_on_offset(dt) == expected def test_repr(self): assert ( repr(LastWeekOfMonth(n=2, weekday=1)) == "<2 * LastWeekOfMonths: weekday=1>" )