holidays Python Library

repository·dev·Indexed 23 days ago

https://github.com/vacanza/holidays

An Open World Holidays Framework and fast Python library for generating country- and subdivision-specific government holidays. It provides dict-like interfaces to determine if a date is a holiday and retrieve holiday names. The library supports 250 country codes (ISO 3166-1 alpha-2), subdivisions (ISO 3166-2), various languages (ISO 639-1/2), and financial markets via MIC codes. It includes support for different holiday categories such as PUBLIC, BANK, and SCHOOL, and allows exporting calendars to ICS files.

Tokens
14.4K
Snippets
21
Records
70
Agent score
78%

What's inside holidays

  1. Combine multiple holiday objects

    dev
    You can merge multiple holiday objects using the + operator or the += in-place addition. The resulting object will contain the union of all holidays from the initial objects. You can also use the built-in sum() function to combine a list of holiday objects (e.g., combining all subdivisions of a country).
  2. Filter holidays by category

    dev

    Beyond standard national holidays, many countries support specific holiday categories.

    • PUBLIC Holidays: All supported countries include the PUBLIC category by default.
    • Other Categories: Depending on the country, you may be able to access bank holidays, school holidays, additional holidays (paid/non-paid), state or public employee holidays, or religious holidays.
    • Checking Support: Use the supported_categories attribute for a country to determine which specific holiday types are available.
  3. Identify supported countries and subdivisions

    dev

    The holidays library supports 250 country codes, primarily following the ISO 3166-1 alpha-2 standard (e.g., US, GB). For more granular holiday data, you can use ISO 3166-2 codes to specify subdivisions.

    Some subdivisions include subdivisions_aliases to support common or officially recognized alternative names. When using these, ensure you are targeting the correct subdivision code or its recognized alias.

  4. Configure the `observed` parameter

    dev
    The observed parameter (defaulting to True) determines if holidays falling on weekends are included as 'observed' holidays on the following Monday (or other designated day). You can toggle this on the fly by setting holiday_obj.observed = False to only include the actual holiday date, or True to include observed dates.
  5. Specify languages for holiday names

    dev

    Holiday names can be output in different languages depending on the country's support.

    • Language Codes: The library uses ISO 639-1 codes (e.g., en, fr) as the primary standard. If an ISO 639-1 code is unavailable, ISO 639-2 codes may be used.
    • Fallback Behavior: Each country entity may have a default_language attribute. This is used as a fallback if the language you specify is not available for that country.
    • Checking Support: You can check the supported_languages attribute for a specific country to see which languages are available for holiday name output.
  6. Configure the `expand` parameter

    dev
    The expand parameter (defaulting to True) controls whether the Holiday object automatically calculates and adds holidays for new years when a date outside the initial years range is queried. You can toggle this on the fly by setting holiday_obj.expand = False to prevent the object from growing, or True to allow it to expand.
  7. How DE_FACTO categories affect working day calculations

    dev

    In some countries, certain observances are not officially 'public holidays' but are legally treated as such for calculating working days (e.g., in Sweden). To ensure accurate is_working_day() behavior in these cases, you must include the DE_FACTO category when initializing the country object.

    import holidays
    from holidays.constants import PUBLIC, DE_FACTO
    
    # In Sweden, Midsummer Eve is DE_FACTO, not PUBLIC.
    # Including DE_FACTO ensures is_working_day() returns False for it.
    se = holidays.Sweden(categories=(PUBLIC, DE_FACTO), years=2024)
    print(se.is_working_day('2024-12-24'))  # False
  8. Use helper methods to add complex holidays

    dev

    When inheriting from HolidayBase, you can use specialized _add_holiday_* methods to define holidays based on patterns rather than fixed dates. Supported patterns include:

    • _add_holiday_<month>_<day>: Fixed dates (e.g., _add_holiday_jan_1).
    • _add_holiday_<last/nth>_<weekday>_of_<month>: Specific weekdays (e.g., _add_holiday_last_mon_of_feb).
    • _add_holiday_<n>_day(s)_<past/prior>_<last/nth>_<weekday>_of_<month>: Relative to a weekday (e.g., _add_holiday_2_days_prior_2nd_mon_of_jan).
    • _add_holiday_<nth>_<weekday>_<before/from>_<month>_<day>: Relative to a date (e.g., _add_holiday_1st_tue_from_dec_25).
    • _add_holiday_<n>_day(s)_<prior/past>_easter: Relative to Easter (requires inheritance from ChristianHolidays).
    import holidays
    
    class MovingHolidays(holidays.HolidayBase):
        def _populate(self, year):
            super()._populate(year)
            self._add_holiday_3rd_mon_of_jan("Martin Luther King Jr. Day")
            self._add_holiday_last_fri_of_feb("Last Friday of February")
            self._add_holiday_1st_mon_before_dec_25("Monday before Christmas")
    
    moving = MovingHolidays(years=2025)
  9. Create a new holiday class from scratch using HolidayBase

    dev

    If you need to define holidays for an unsupported country, inherit from holidays.HolidayBase. Since HolidayBase has an empty _populate method, you must manually define all holidays within the _populate method using dictionary-style assignment self[date] = "Name".

    import holidays
    from datetime import date
    
    class NewCountryHolidays(holidays.HolidayBase):
        def _populate(self, year):
            self[date(year, 1, 2)] = "Some Federal Holiday"
            self[date(year, 2, 3)] = "Another Federal Holiday"
    
    hdays = NewCountryHolidays()
  10. Include subdivision-specific holidays in a custom class

    dev

    You can implement logic for subdivision-specific holidays (like states or provinces) by checking the self.subdiv attribute within the _populate method.

    import holidays
    from datetime import date
    
    class NewCountryHolidays(holidays.HolidayBase):
        def _populate(self, year):
            if self.subdiv == None:
                self.subdiv = 'XX'
            self[date(year, 1, 2)] = "Some Federal Holiday"
            if self.subdiv == 'XX':
                self[date(year, 2, 3)] = "Special XX subdiv-only holiday"
            if self.subdiv == 'YY':
                self[date(year, 3, 4)] = "Special YY subdiv-only holiday"
    
    hdays = NewCountryHolidays(subdiv='XX')
  11. Apply for a sponsored task

    dev

    To participate in the sponsorship program, follow these steps:

    1. Verify Eligibility:
      • You must have at least one merged pull request that adds support for a new entity's holidays.
      • You must not be currently receiving payment through other structured coding programs (e.g., GSoC, Outreachy).
      • You must have a GitHub Sponsors account (or be eligible for alternative payments like USDT on a case-by-case basis).
    2. Find a Task: Look for issues labeled with sponsorship, sponsorship-medium, or sponsorship-hard.
    3. Express Interest: Comment on the issue expressing your interest. Issues remain open for applications for at least 7 days.
    4. Wait for Assignment: Do not start work until the issue is officially assigned to you (your GitHub username must appear in the assignee field).

    Selection Logic: If multiple people apply, priority is given to new eligible contributors who have not yet participated in the sponsorship program to ensure fair distribution.