267 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from datetime import datetime
 | 
						|
 | 
						|
import pytest
 | 
						|
from pytz import utc
 | 
						|
 | 
						|
import pandas._testing as tm
 | 
						|
 | 
						|
from pandas.tseries.holiday import (
 | 
						|
    MO,
 | 
						|
    SA,
 | 
						|
    AbstractHolidayCalendar,
 | 
						|
    DateOffset,
 | 
						|
    EasterMonday,
 | 
						|
    GoodFriday,
 | 
						|
    Holiday,
 | 
						|
    HolidayCalendarFactory,
 | 
						|
    Timestamp,
 | 
						|
    USColumbusDay,
 | 
						|
    USLaborDay,
 | 
						|
    USMartinLutherKingJr,
 | 
						|
    USMemorialDay,
 | 
						|
    USPresidentsDay,
 | 
						|
    USThanksgivingDay,
 | 
						|
    get_calendar,
 | 
						|
    next_monday,
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize(
 | 
						|
    "holiday,start_date,end_date,expected",
 | 
						|
    [
 | 
						|
        (
 | 
						|
            USMemorialDay,
 | 
						|
            datetime(2011, 1, 1),
 | 
						|
            datetime(2020, 12, 31),
 | 
						|
            [
 | 
						|
                datetime(2011, 5, 30),
 | 
						|
                datetime(2012, 5, 28),
 | 
						|
                datetime(2013, 5, 27),
 | 
						|
                datetime(2014, 5, 26),
 | 
						|
                datetime(2015, 5, 25),
 | 
						|
                datetime(2016, 5, 30),
 | 
						|
                datetime(2017, 5, 29),
 | 
						|
                datetime(2018, 5, 28),
 | 
						|
                datetime(2019, 5, 27),
 | 
						|
                datetime(2020, 5, 25),
 | 
						|
            ],
 | 
						|
        ),
 | 
						|
        (
 | 
						|
            Holiday("July 4th Eve", month=7, day=3),
 | 
						|
            "2001-01-01",
 | 
						|
            "2003-03-03",
 | 
						|
            [Timestamp("2001-07-03 00:00:00"), Timestamp("2002-07-03 00:00:00")],
 | 
						|
        ),
 | 
						|
        (
 | 
						|
            Holiday("July 4th Eve", month=7, day=3, days_of_week=(0, 1, 2, 3)),
 | 
						|
            "2001-01-01",
 | 
						|
            "2008-03-03",
 | 
						|
            [
 | 
						|
                Timestamp("2001-07-03 00:00:00"),
 | 
						|
                Timestamp("2002-07-03 00:00:00"),
 | 
						|
                Timestamp("2003-07-03 00:00:00"),
 | 
						|
                Timestamp("2006-07-03 00:00:00"),
 | 
						|
                Timestamp("2007-07-03 00:00:00"),
 | 
						|
            ],
 | 
						|
        ),
 | 
						|
        (
 | 
						|
            EasterMonday,
 | 
						|
            datetime(2011, 1, 1),
 | 
						|
            datetime(2020, 12, 31),
 | 
						|
            [
 | 
						|
                Timestamp("2011-04-25 00:00:00"),
 | 
						|
                Timestamp("2012-04-09 00:00:00"),
 | 
						|
                Timestamp("2013-04-01 00:00:00"),
 | 
						|
                Timestamp("2014-04-21 00:00:00"),
 | 
						|
                Timestamp("2015-04-06 00:00:00"),
 | 
						|
                Timestamp("2016-03-28 00:00:00"),
 | 
						|
                Timestamp("2017-04-17 00:00:00"),
 | 
						|
                Timestamp("2018-04-02 00:00:00"),
 | 
						|
                Timestamp("2019-04-22 00:00:00"),
 | 
						|
                Timestamp("2020-04-13 00:00:00"),
 | 
						|
            ],
 | 
						|
        ),
 | 
						|
        (
 | 
						|
            GoodFriday,
 | 
						|
            datetime(2011, 1, 1),
 | 
						|
            datetime(2020, 12, 31),
 | 
						|
            [
 | 
						|
                Timestamp("2011-04-22 00:00:00"),
 | 
						|
                Timestamp("2012-04-06 00:00:00"),
 | 
						|
                Timestamp("2013-03-29 00:00:00"),
 | 
						|
                Timestamp("2014-04-18 00:00:00"),
 | 
						|
                Timestamp("2015-04-03 00:00:00"),
 | 
						|
                Timestamp("2016-03-25 00:00:00"),
 | 
						|
                Timestamp("2017-04-14 00:00:00"),
 | 
						|
                Timestamp("2018-03-30 00:00:00"),
 | 
						|
                Timestamp("2019-04-19 00:00:00"),
 | 
						|
                Timestamp("2020-04-10 00:00:00"),
 | 
						|
            ],
 | 
						|
        ),
 | 
						|
        (
 | 
						|
            USThanksgivingDay,
 | 
						|
            datetime(2011, 1, 1),
 | 
						|
            datetime(2020, 12, 31),
 | 
						|
            [
 | 
						|
                datetime(2011, 11, 24),
 | 
						|
                datetime(2012, 11, 22),
 | 
						|
                datetime(2013, 11, 28),
 | 
						|
                datetime(2014, 11, 27),
 | 
						|
                datetime(2015, 11, 26),
 | 
						|
                datetime(2016, 11, 24),
 | 
						|
                datetime(2017, 11, 23),
 | 
						|
                datetime(2018, 11, 22),
 | 
						|
                datetime(2019, 11, 28),
 | 
						|
                datetime(2020, 11, 26),
 | 
						|
            ],
 | 
						|
        ),
 | 
						|
    ],
 | 
						|
)
 | 
						|
def test_holiday_dates(holiday, start_date, end_date, expected):
 | 
						|
    assert list(holiday.dates(start_date, end_date)) == expected
 | 
						|
 | 
						|
    # Verify that timezone info is preserved.
 | 
						|
    assert list(
 | 
						|
        holiday.dates(
 | 
						|
            utc.localize(Timestamp(start_date)), utc.localize(Timestamp(end_date))
 | 
						|
        )
 | 
						|
    ) == [utc.localize(dt) for dt in expected]
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize(
 | 
						|
    "holiday,start,expected",
 | 
						|
    [
 | 
						|
        (USMemorialDay, datetime(2015, 7, 1), []),
 | 
						|
        (USMemorialDay, "2015-05-25", [Timestamp("2015-05-25")]),
 | 
						|
        (USLaborDay, datetime(2015, 7, 1), []),
 | 
						|
        (USLaborDay, "2015-09-07", [Timestamp("2015-09-07")]),
 | 
						|
        (USColumbusDay, datetime(2015, 7, 1), []),
 | 
						|
        (USColumbusDay, "2015-10-12", [Timestamp("2015-10-12")]),
 | 
						|
        (USThanksgivingDay, datetime(2015, 7, 1), []),
 | 
						|
        (USThanksgivingDay, "2015-11-26", [Timestamp("2015-11-26")]),
 | 
						|
        (USMartinLutherKingJr, datetime(2015, 7, 1), []),
 | 
						|
        (USMartinLutherKingJr, "2015-01-19", [Timestamp("2015-01-19")]),
 | 
						|
        (USPresidentsDay, datetime(2015, 7, 1), []),
 | 
						|
        (USPresidentsDay, "2015-02-16", [Timestamp("2015-02-16")]),
 | 
						|
        (GoodFriday, datetime(2015, 7, 1), []),
 | 
						|
        (GoodFriday, "2015-04-03", [Timestamp("2015-04-03")]),
 | 
						|
        (EasterMonday, "2015-04-06", [Timestamp("2015-04-06")]),
 | 
						|
        (EasterMonday, datetime(2015, 7, 1), []),
 | 
						|
        (EasterMonday, "2015-04-05", []),
 | 
						|
        ("New Year's Day", "2015-01-01", [Timestamp("2015-01-01")]),
 | 
						|
        ("New Year's Day", "2010-12-31", [Timestamp("2010-12-31")]),
 | 
						|
        ("New Year's Day", datetime(2015, 7, 1), []),
 | 
						|
        ("New Year's Day", "2011-01-01", []),
 | 
						|
        ("Independence Day", "2015-07-03", [Timestamp("2015-07-03")]),
 | 
						|
        ("Independence Day", datetime(2015, 7, 1), []),
 | 
						|
        ("Independence Day", "2015-07-04", []),
 | 
						|
        ("Veterans Day", "2012-11-12", [Timestamp("2012-11-12")]),
 | 
						|
        ("Veterans Day", datetime(2015, 7, 1), []),
 | 
						|
        ("Veterans Day", "2012-11-11", []),
 | 
						|
        ("Christmas Day", "2011-12-26", [Timestamp("2011-12-26")]),
 | 
						|
        ("Christmas Day", datetime(2015, 7, 1), []),
 | 
						|
        ("Christmas Day", "2011-12-25", []),
 | 
						|
        ("Juneteenth National Independence Day", "2020-06-19", []),
 | 
						|
        (
 | 
						|
            "Juneteenth National Independence Day",
 | 
						|
            "2021-06-18",
 | 
						|
            [Timestamp("2021-06-18")],
 | 
						|
        ),
 | 
						|
        ("Juneteenth National Independence Day", "2022-06-19", []),
 | 
						|
        (
 | 
						|
            "Juneteenth National Independence Day",
 | 
						|
            "2022-06-20",
 | 
						|
            [Timestamp("2022-06-20")],
 | 
						|
        ),
 | 
						|
    ],
 | 
						|
)
 | 
						|
def test_holidays_within_dates(holiday, start, expected):
 | 
						|
    # see gh-11477
 | 
						|
    #
 | 
						|
    # Fix holiday behavior where holiday.dates returned dates outside
 | 
						|
    # start/end date, or observed rules could not be applied because the
 | 
						|
    # holiday was not in the original date range (e.g., 7/4/2015 -> 7/3/2015).
 | 
						|
    if isinstance(holiday, str):
 | 
						|
        calendar = get_calendar("USFederalHolidayCalendar")
 | 
						|
        holiday = calendar.rule_from_name(holiday)
 | 
						|
 | 
						|
    assert list(holiday.dates(start, start)) == expected
 | 
						|
 | 
						|
    # Verify that timezone info is preserved.
 | 
						|
    assert list(
 | 
						|
        holiday.dates(utc.localize(Timestamp(start)), utc.localize(Timestamp(start)))
 | 
						|
    ) == [utc.localize(dt) for dt in expected]
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize(
 | 
						|
    "transform", [lambda x: x.strftime("%Y-%m-%d"), lambda x: Timestamp(x)]
 | 
						|
)
 | 
						|
def test_argument_types(transform):
 | 
						|
    start_date = datetime(2011, 1, 1)
 | 
						|
    end_date = datetime(2020, 12, 31)
 | 
						|
 | 
						|
    holidays = USThanksgivingDay.dates(start_date, end_date)
 | 
						|
    holidays2 = USThanksgivingDay.dates(transform(start_date), transform(end_date))
 | 
						|
    tm.assert_index_equal(holidays, holidays2)
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize(
 | 
						|
    "name,kwargs",
 | 
						|
    [
 | 
						|
        ("One-Time", {"year": 2012, "month": 5, "day": 28}),
 | 
						|
        (
 | 
						|
            "Range",
 | 
						|
            {
 | 
						|
                "month": 5,
 | 
						|
                "day": 28,
 | 
						|
                "start_date": datetime(2012, 1, 1),
 | 
						|
                "end_date": datetime(2012, 12, 31),
 | 
						|
                "offset": DateOffset(weekday=MO(1)),
 | 
						|
            },
 | 
						|
        ),
 | 
						|
    ],
 | 
						|
)
 | 
						|
def test_special_holidays(name, kwargs):
 | 
						|
    base_date = [datetime(2012, 5, 28)]
 | 
						|
    holiday = Holiday(name, **kwargs)
 | 
						|
 | 
						|
    start_date = datetime(2011, 1, 1)
 | 
						|
    end_date = datetime(2020, 12, 31)
 | 
						|
 | 
						|
    assert base_date == holiday.dates(start_date, end_date)
 | 
						|
 | 
						|
 | 
						|
def test_get_calendar():
 | 
						|
    class TestCalendar(AbstractHolidayCalendar):
 | 
						|
        rules = []
 | 
						|
 | 
						|
    calendar = get_calendar("TestCalendar")
 | 
						|
    assert TestCalendar == type(calendar)
 | 
						|
 | 
						|
 | 
						|
def test_factory():
 | 
						|
    class_1 = HolidayCalendarFactory(
 | 
						|
        "MemorialDay", AbstractHolidayCalendar, USMemorialDay
 | 
						|
    )
 | 
						|
    class_2 = HolidayCalendarFactory(
 | 
						|
        "Thanksgiving", AbstractHolidayCalendar, USThanksgivingDay
 | 
						|
    )
 | 
						|
    class_3 = HolidayCalendarFactory("Combined", class_1, class_2)
 | 
						|
 | 
						|
    assert len(class_1.rules) == 1
 | 
						|
    assert len(class_2.rules) == 1
 | 
						|
    assert len(class_3.rules) == 2
 | 
						|
 | 
						|
 | 
						|
def test_both_offset_observance_raises():
 | 
						|
    # see gh-10217
 | 
						|
    msg = "Cannot use both offset and observance"
 | 
						|
    with pytest.raises(NotImplementedError, match=msg):
 | 
						|
        Holiday(
 | 
						|
            "Cyber Monday",
 | 
						|
            month=11,
 | 
						|
            day=1,
 | 
						|
            offset=[DateOffset(weekday=SA(4))],
 | 
						|
            observance=next_monday,
 | 
						|
        )
 |