pax_global_header00006660000000000000000000000064145701363340014520gustar00rootroot0000000000000052 comment=7583797cd1432111bfcd80e65991add8fa412a30 calendra-7.9.0/000077500000000000000000000000001457013633400133065ustar00rootroot00000000000000calendra-7.9.0/.coveragerc000066400000000000000000000003101457013633400154210ustar00rootroot00000000000000[run] omit = # leading `*/` for pytest-dev/pytest-cov#456 */.tox/* disable_warnings = couldnt-parse [report] show_missing = True exclude_also = # jaraco/skeleton#97 @overload if TYPE_CHECKING: calendra-7.9.0/.editorconfig000066400000000000000000000003661457013633400157700ustar00rootroot00000000000000root = true [*] charset = utf-8 indent_style = tab indent_size = 4 insert_final_newline = true end_of_line = lf [*.py] indent_style = space max_line_length = 88 [*.{yml,yaml}] indent_style = space indent_size = 2 [*.rst] indent_style = space calendra-7.9.0/.github/000077500000000000000000000000001457013633400146465ustar00rootroot00000000000000calendra-7.9.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000032321457013633400204470ustar00rootroot00000000000000refs # For information, read and make sure you're okay with the [Contributing guidelines](https://workalendar.github.io/workalendar/contributing.html#adding-new-calendars). - [ ] Tests with a significant number of years to be tested for your calendar. - [ ] Docstrings for the Calendar class and specific methods. - [ ] Use the ``workalendar.registry_tools.iso_register`` decorator to register your new calendar using ISO codes (optional). - [ ] Calendar country / label added to the README.md file. - [ ] Changelog amended with a mention like: "Added ```` by ``@pseudo`` (#)". **Note** *Please do NOT change the version number here. It's the project maintainers' duty.* - [ ] Tests with a significant number of years to be tested for your calendar. - [ ] Changelog amended with a mention describing your changes. **Note** *Please do NOT change the version number here. It's the project maintainers' duty.* calendra-7.9.0/.github/dependabot.yml000066400000000000000000000002241457013633400174740ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "pip" directory: "/" schedule: interval: "daily" allow: - dependency-type: "all" calendra-7.9.0/.github/workflows/000077500000000000000000000000001457013633400167035ustar00rootroot00000000000000calendra-7.9.0/.github/workflows/main.yml000066400000000000000000000052651457013633400203620ustar00rootroot00000000000000name: tests on: merge_group: push: branches-ignore: # disabled for jaraco/skeleton#103 # - gh-readonly-queue/** # Temporary merge queue-related GH-made branches pull_request: permissions: contents: read env: # Environment variable to support color support (jaraco/skeleton#66) FORCE_COLOR: 1 # Suppress noisy pip warnings PIP_DISABLE_PIP_VERSION_CHECK: 'true' PIP_NO_PYTHON_VERSION_WARNING: 'true' PIP_NO_WARN_SCRIPT_LOCATION: 'true' # Ensure tests can sense settings about the environment TOX_OVERRIDE: >- testenv.pass_env+=GITHUB_*,FORCE_COLOR jobs: test: strategy: matrix: python: - "3.8" - "3.11" - "3.12" platform: - ubuntu-latest - macos-latest - windows-latest include: - python: "3.9" platform: ubuntu-latest - python: "3.10" platform: ubuntu-latest - python: pypy3.10 platform: ubuntu-latest runs-on: ${{ matrix.platform }} continue-on-error: ${{ matrix.python == '3.13' }} steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} allow-prereleases: true - name: Install tox run: python -m pip install tox - name: Run run: tox collateral: strategy: fail-fast: false matrix: job: - diffcov - docs runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.x - name: Install tox run: python -m pip install tox - name: Eval ${{ matrix.job }} run: tox -e ${{ matrix.job }} check: # This job does nothing and is only used for the branch protection if: always() needs: - test - collateral runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} release: permissions: contents: write needs: - check if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.x - name: Install tox run: python -m pip install tox - name: Run run: tox -e release env: TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} calendra-7.9.0/.pre-commit-config.yaml000066400000000000000000000001641457013633400175700ustar00rootroot00000000000000repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.8 hooks: - id: ruff - id: ruff-format calendra-7.9.0/.readthedocs.yaml000066400000000000000000000003041457013633400165320ustar00rootroot00000000000000version: 2 python: install: - path: . extra_requirements: - docs # required boilerplate readthedocs/readthedocs.org#10401 build: os: ubuntu-lts-latest tools: python: latest calendra-7.9.0/LICENSE000066400000000000000000000017771457013633400143270ustar00rootroot00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. calendra-7.9.0/NEWS.rst000066400000000000000000001124101457013633400146130ustar00rootroot00000000000000v7.9.0 ====== Features -------- - Coronation of His Majesty King Charles III Bank holiday in 2023 to the UK calendar. v7.8.0 ====== Features -------- - Added China holidays for 2024. v7.7.1 ====== No significant changes. v7.7.0 ====== Features -------- - Incorporate changes from workalendar v17.0.0 (2023-01-01) New calendars - New calendar: Added Tunisia calendar by @macharmi (#702) - New calendar: Added El Salvador calendar by @hersoncruz (#708). Other changes - Update China's public holidays for 2023 (#728). - Removed compatibility with Python 3.6, also, removed tests & amended documentation (#705). - Upgraded `tox` usage, now compatble with tox 4+ (added `allowlist_externals`). - Added support for Python 3.10 (#706). - Added support for Python 3.11 (#732). - Refactor ``NetherlandsWithSchoolHolidays.get_christmas_holidays`` for simplicity and readability. - Incorporate changes from workalendar v16.4.0 (2022-09-16) - Fixed United Kingdom's 2022 holidays ; Added Bank Holiday for the State Funeral of Queen Elizabeth II (#719). - Require Python 3.8 or later. v7.6.1 ====== Updated some latent references to peopledoc. v7.6.0 ====== Internal refactoring and simplification. Removed redundant "shift" holidays from european countries. v7.5.0 ====== Incorporate changes from workalendar v16.3.0 (2022-02-22) Calendars - New calendar: Added Georgia (country) calendar by @atj01 (#687). - New calendar: Added Kazakhstan calendar by @atj01 (#688). - New calendar: Added USA Federal Reserve System calendar by @ludsoft (#695) Bugfixes and other changes - Removed duplicate Proclamation Day for Latvia, by @Daglina (#686). - Documentation: Fix the ``keep_datetime`` usage example in the "basic" doc (#690). - Added conditional holidays on 26th December and 2nd January in Neuchatel (Switzerland) (#697). - Added Federal Thanksgiving Monday and two conditional holidays on 26th December and 2nd January in Neuchatel (Switzerland) (#697). Incorporate changes from workalendar v16.2.0 (2021-12-10) - Update China's public holidays for 2022, thx to @iamsk (#693). Incorporate changes from workalendar v16.1.0 (2021-10-01) - Fixed United Kingdom's 2022 holidays ; Spring Bank Holiday has been moved to the 3rd of June and Queen's Platinum Jubilee added to 2nd of June. - New calendar: Added Guernsey calendar by @ludsoft (#681) v7.4.0 ====== Incorporate changes from workalendar v16.0.0 (2021-09-16) Calendars - New calendar: Added Philippines calendar by @micodls (#396) Internal - Remove `skyfield` dependency, added `[astronomy]` as extra dependency (#660). - Replace `pyCalverter` with `convertdate` (#536). - Remove unused `JalaliMixin` - Replace `pkg_resources` with `importlib_metadata` to fetch the version number in `__init__.py` (#657) - Added new badges (pypi, conda, license) and installation instructions (pip, conda) to readme file @sugatoray (#673). - Added the "Workalendar maintainers" in the LICENSE file. - Changed the maintainer email. v7.3.0 ====== Incorporate changes from workalendar v15.4.0 (2021-07-12) - New calendar: Added Nigeria calendar by @taiyeoguns (#656) - Fix: Chilean calendar floating dates, add Indigenous Peoples Day using solar term, thx @ajcobo. Incorporate changes from workalendar v15.3.1 (2021-07-02) Bugfixes - Updated Japan calendar because of the Olympics, thx @lxlgarnett. (#662) - Fixed Japan "Sports Day" label depending on the year. Documentation - The Workalendar project has been moved from Peopledoc's organization to its own (#651, #653, thx to @ewjoachim). Incorporate changes from workalendar v15.3.0 (2021-05-07) - Fix Barbados calendar to add 2 non computable public holiday and fix boxing day computation, thx to @ludsoft (#647). Incorporate changes from workalendar v15.2.0 (2021-04-23) - Fixed Cuiaba City calendar (Brazil), adding Easter Sunday, Corpus Christi and Good Friday, thx @leogregianin (#642). - Fix Catalonian calendar: add missing St John the Baptist public holiday, thx @lozlow (#643). Incorporate changes from workalendar v15.1.0 (2021-03-12) - Bugfix: Bulgaria holidays are now computed using the Orthodox calendar, include shifting rules for holidays that fall on a week-end (#596). - Bugfix: `get_working_days_delta` method to integrate the `extra_holidays` and `extra_working_days` args (#631). Incorporate changes from workalendar v15.0.2 (2021-03-05) - Bugfix: USA calendar would take the `shift_exceptions` into account, even if the exceptions are set in the next or previous year (#610). - Requirements: Unpin `pyupgrade` library (#634). Incorporate changes from workalendar v15.0.1 (2021-02-26) - Hotfix: Taiwan exceptional working day on February, 20th 2021 (#628). - Hotfix: September 11th is a working day in Taiwan (#628). v7.2.0 ====== Incorporate changes from workalendar v15.0.0 (2021-02-19) Major changes - API: New method available in `core` module: `Calendar.get_iso_week_date()` to find the weekday X of the week number Y (#619). - Requirements: Replace pytz with `(backports.)zoneinfo`, thx to @eumiro (#614) - Doc: Documented the different (in)compatibilities due to the use of `zoneinfo` (#614). Bugfixes - Small fixes in Netherlands School calendars (#619). - Temporary downgrade of `pyupgrade` to fix the `pyup_dirs`. Improving test coverage - Improve Netherlands coverage (#546, #619). - Improve Russia coverage (#546). - Improve USA calendar coverage by removing a method that wasn't used anyways (`get_washington_birthday_december()`). The method is implemented in both Indiana and Georgia State calendars, and is specific for each state, even if they look very similar (#546). - Improve the `astronomy.py` module coverage (#546). - Improve coverage for the `tests/__init__.py` module (#546). *Note:* system-dependant test branch (if Windows) won't be counted for coverage. v7.1.0 ====== Incorporate changes from workalendar v14.3.0 (2021-01-15) Calendars - Update Malaysia 2022-2024 (Deepavali + Thaipusam) by @jack-pace Incorporate changes from workalendar v14.2.0 (2021-01-08) Calendars - Update Singapore for range from 2022 to 2030 (Deepavali), by @hprobotic Internal - Replace `os.path.*` calls with `pathlib.Path`, thx to @eumiro (#603) - Use f-string for string formatting, thx to @eumiro (#605) - Simplify collections handling, thx to @eumiro (#606) - Use integers for time units divisions, thx to @eumiro - Adding Mac OS & Windows tests to the test matrix (related to #607). - Fix tests when running them on Windows (#607). v7.0.0 ====== New feature - Enhanced support for multi-day "series" holidays such as Chinese Spring Festival and Islamic Eid. Previously, if one day of the series was shifted as per the observance shift rules, it would "merge" into the next day of the series, effectively shortening the observed series. Now, all the following days of the series are shifted, maintaining its duration. Incorporate changes from workalendar v14.1.0 (2020-12-10) - Fix Russia 2021 holidays, thx @MichalChromcak for the bug report (#578). Incorporate changes from workalendar v14.0.0 (2020-11-27) - Fixes - Fix Russia calendar: non-working days are shifted to the next MON when they happen on the week-end (#589). - Fix Russia New year holidays. It has become a week off since 2005 (related to #578). - Added Russia COVID-19 non-working days for the year 2020 ; these days are not shifted to next MON (#578). - Fixed Russia Christmas day ; December 25th is not a public holiday. Fixed several other Orthodox calendars (#530). - Update China's public holidays for 2021, thanks @iamsk. - Minor changes - Added a `daterange` function in `workalendar.core` module to iterate between two dates. Incorporate changes from workalendar v13.0.0 (2020-11-13) - Calendars - Add optional school holidays to Netherlands calendar, by @Flix6x (#556). - Add optional carnival to Netherlands calendar. - Documentation - Moving the `contributing.md` file to the `docs/` directory (#573). - Changed from `setup.py` to a nice `setup.cfg` file, thanks @ewjoachim (#576). - Added documentation about class options (#572). - Converted `README.rst` file into `README.md` (#575). - Fixed Pull Request template to reference `setup.cfg` (#587). - Other changes - Switched from Travis CI to Github Actions for CI jobs, thanks to @mgu. - Added support of Python 3.9 (#557). - Changed from `setup.py` to a nice `setup.cfg` file, thanks @ewjoachim (#576). - Use the `setup.cfg` file in the key to cache in `ci.yml` file (#587). - [OBSOLETE] Switched from bionic to focal on Travis CI (we've switched to GH actions after that). Incorporate changes from workalendar v12.1.0 (2020-10-16) - New calendars - Added Spain regions: Andalusia, Aragon, Castile and León, Castilla-La Mancha, Canary Islands, Extremadura, Galicia, Balearic Islands, La Rioja, Community of Madrid, Murcia, Navarre, Asturias, Basque Country, Cantabria, Valencian Community (#531). - Added all ISO codes for Spain regions - thx @ainarela for your help on this (#531). - Other changes - Refactored Spain test modules (#531). - Fix Catalonia calendar by removing *Sant Juan* day, which does not appear to be an official holiday (#531). - Improve coverage of `workalendar/core.py` module (#546). - Improve coverage for the Netherlands calendar - Queen's Day (#546). - Improve coverage for the Romania calendar - Liberation day (#546). - Improve coverage for the New Zealand calendar (#546). - Added a tox entrypoint to ensure code is Python 3.6+, using ``pyupgrade`` (#566). - Added the pyupgrade tox job to the test suite, amended contributing documentation (#566). Incorporate changes from workalendar v12.0.0 (2020-10-02) - **Deprecation:** Dropped support for Python 3.5. As of this version, workalendar now requires Python 3.6+ (#330). - Improve coverage of Singapore calendar (#546). Incorporate changes from workalendar v11.0.1 (2020-09-11) - Add ISO code decorator to Catalonia calendar, thanks to @jbagot (#551). - Improve coverage of South Africa calendar (#546). - Improve coverage of Brazil calendar (#546). - Improve coverage of Canada (Nunavut) calendar (#546). - Improve coverage of Israel calendar (#546). Incorporate changes from workalendar v11.0.0 (2020-09-04) - New calendar - Added Mozambique calendar by @mr-shovel (#542). - New feature - Added iCal export feature, initiated by @joooeey (#197). - Fix PRODID pattern for iCal exports: `"PRODID:-//workalendar//ical {__version__}//EN"`, using current workalendar version (#543). Incorporate changes from workalendar v10.4.0 (2020-08-28) - New calendar - Added Monaco calendar by @joaopbnogueira (#538). - Major changes and bugfixes - Migrating Labour Day as a worldwide holiday, disabled by default, but activated (to date) for about 50 countries (including label change when necessary), `contributing.md` documentation amended (#467). - Bugfix: Avoid Cesar Chavez Day duplicated shifts by refactoring the California shift rules (#528). - Other changes - Small refactoring for the Colombia / added docstrings & comments to explain why we're not using stock options. Added tests for year 2020 and handling shift exceptions (#509). - Tech: Replace occurrences of `assertEquals` with `assertEqual` to clear warnings (#533). - Use `include_immaculate_conception` flag for Portugal, Brazil, Argentina, Paraguay calendars (#529). Incorporate changes from workalendar v10.3.0 (2020-07-10) - Bugfixes - Belarus: removing day after Radonitsa, which is apparently not a holiday. - Algeria: assigning the week-end days as FRI+SAT, as it's following a Islamic calendar. - Other changes - Refactoring the core ``Calendar`` classes / mixins for better understanding. Only one ``Calendar`` subclass should be imported / used in calendar classes, the rest (when possible) should be ``Mixins`` (related to #511). - Declaring the New year's Day as a worldwide holiday, with only two exceptions (to date): Israel & Qatar (#511). - Fixed `contributing.md` documentation with the new class/mixin organization (#511). Incorporate changes from workalendar v10.2.0 (2020-06-26) - Bugfix: setting *Consciência Negra day* as a non-holiday by default for Brazilian calendars, thx to @edniemeyer (#516). - Bugfix: Introducing the changes in Croatia holidays as of 2020 - Remembrance Day, Independence Day, Statehood Day... thx to @davidpodrebarac for the bug report (#515). Incorporate changes from workalendar v10.1.0 (2020-06-18) - Calendar fix - Adding All Souls' Day to Lithuania calendar, starting of 2020, thx to @norkunas (#512). - Minor changes - Small fixes (docstrings, use of extends, etc) on Cayman Islands calendar (#507). - Moving Carnaval / Mardi Gras / Fat Tuesday calculation into the `workalendar.core` module, because it's used in at least 3 countries and some States / Counties in the USA. Incorporate changes from workalendar v10.0.0 (2020-06-05) - **BREAKING CHANGE**: the ``IsoRegistry.get_calendar_class()`` method has been removed from the code and should no longer be used (#375, #495). Incorporate changes from workalendar v9.2.0 (2020-06-02) - New Calendars - Added rules for all Switzerland Cantons, branching off the initial work by @brutasse (#497). Incorporate changes from workalendar v9.0.1 (2020-05-22) - Making the Israel calendar more efficient (#498). - Fixing duplicated holidays in Hong-Kong and Hong-Kong Bank holiday calendars (#496). - Integrating Hong-Kong holidays for 2021 (#496). Incorporate changes from workalendar v9.0.0 (2020-04-24) - **BREAKING CHANGE**: the ``IsoRegistry.items()`` method has been removed from the API. You must use the ``get_calendars()`` to perform the same registry queries (#375, #491). - *Deprecation notice*: The usage of ``IsoRegistry.get_calendar_class()`` is strongly discouraged, in favor of ``get()``. The ``get_calendar_class`` method will be dropped in a further release. In the meantime, they'll be both equivalent (#375, #418). Incorporate changes from workalendar v8.4.0 (2020-04-17) - New Calendar - Added Kenyan calendar, by @KidkArolis (#484) - Minor fixes - Fixed Lithuania calendar to use the core flags for Assumption and All Saints (#468). - Fixed Malta calendar ; January 1st was already included, no need to add it to the ``FIXED_HOLIDAYS`` property (#469). - Small refactor in Netherlands calendar to use core constants (#470). Incorporate changes from workalendar v8.3.0 (2020-04-14) - Fixing Hong-Kong calendar, where SAT are common working days (#477). - Introducing Hong-Kong Bank calendar. For banks, Saturdays are non-working days (#477). Incorporate changes from workalendar v8.2.2 (2020-04-10) - Fixed Argentina's "Malvinas Day" date for 2020, shifted to March 31st because of the coronavirus crisis (#476). - Fixed Argentina's label for "Malvinas Day" and "Día de la Memoria" (#476). Incorporate changes from workalendar v8.2.1 (2020-04-03) - Added BrazilBankCalendar to support `include_` flags and make it possible to extend and change these flags to support custom bank calendars (#474). Incorporate changes from workalendar v8.2.0 (2020-03-13) - Added Belarus calendar, by @alexdoesstuff (#472). Incorporate changes from workalendar v8.1.0 (2020-02-07) - Added Israel holidays eves and removed holidays which are not affecting the working days in Israel (#461). - Fix warning in China's holidays to dynamically read supported years, thx @fredrike (#459). Incorporate changes from workalendar v8.0.2 (2020-01-24) - Fix several miscalculations in Georgia (USA) calendar (#451). Incorporate changes from workalendar v8.0.1 (2020-01-24) - Fix Family Day for British Columbia (Canada) which was switched from 2nd to 3rd Monday of February in 2019 - thx @jbroudou for the bug report (#454). v6.1.2 ====== #14: Replaced implicit dependency on setuptools with explicit dependency on importlib.metadata. v6.1.1 ====== Fix version inference when installed from sdist. v6.1.0 ====== Incorporate changes from workalendar v8.0.0 (2020-01-10) - **BREAKING CHANGE** Drop Support for Python 2 - EOL January 1st 2020 (#442). - Added Ukraine calendar, by @apelloni. - Small cleanup in the ``.travis.yml`` file, thx to @Natim. - Changes in the ``registry.items()`` method API. - This method is aliased to ``get_calendars()``. In a near release, the ``items()`` method will change its purpose. - The ``get_calendars()`` method accepts an empty/missing ``region_codes`` argument to retrieve the full registry. Please see the [ISO Registry documentation](https://workalendar.github.io/workalendar/iso-registry.html) for extensive usage docs (#403, #375). Incorporate changes from workalendar v7.2.0 (2019-12-06) New calendars - Added Serbia calendar, by @apelloni (#435). - Added Argentina calendar, by @ftatarli (#419). Other changes - Update China's public holidays for 2020, thx @nut-free (#429). - Update Malaysia and Singapore for 2021 (Deepavali + Thaipusam) by @jack-pace (#432). - Small refactorings on the Gevena (Switzerland) holiday class, thx to @cw-intellineers (#420). Incorporate changes from workalendar v7.1.1 (2019-11-22) - **Bugfix** for USA: Fixed incorrect implementation for Thanksgiving Friday, thx @deveshvar (#422). - Fix Advanced usage documentation about Thanksgiving Day (#426). - Added Geneva calendar by @cw-intellineers (#420). Incorporate changes from workalendar v7.1.0 (2019-11-15) New calendars - Added 27 Brazil calendars -- thanks a lot to @luismalta & @mileo, (#409 & #415) Enhancements - Added compatibility with Python 3.8 (#406). - Added an IBGE_REGISTER to reference IBGE (brazilian) calendars with related tests (#415). - Improve ISO registry interface by raising an error when trying to register a non-Calendar class (#412). Other changes - Fixes and additions to some Brazil calendars ; again, thanks to @luismalta & @mileo, (#409 & #415) - Fix Denmark, re-add Christmas Eve, which is widely treated as public holiday ; thx to @KidkArolis, (#414). - Increase Malaysia coverage by adding tests for missing Deepavali & Thaipusam. - Increase China coverage by adding tests for special extra-holidays & extra-working days cases. v6.0.0 ====== Require Python 3.6 or later. v5.0.0 ====== #11: Add support for ``__add__`` and ``__sub__`` for ``Holiday`` instances on Python 3.8 and later. Now adding a timedelta to a ``Holiday`` returns another ``Holiday``. Incorporate changes from workalendar v7.0.0 (2019-09-20) - Drop `ephem` astronomical calculation library, in favor of `skyfield` and `skyfield-data` for providing minimal data files to enable computation (#302, #348). Many thanks to @GammaSagittarii for the tremendous help on finding the right way to compute Chinese Solar Terms. Also thanks to @antvig and @DainDwarf for testing the beta version (#398). Incorporate changes from workalendar v6.0.1 (2019-09-17) - Fix Turkey Republic Day (#399, thx to @mhmtozc & @Natim). Incorporate changes from workalendar v6.0.0 (2019-08-02) - **Deprecation Notice:** *The global ISO registry now returns plain `dict` objects from its various methods.* - Global registry now returns plain built-in dicts (#375). - Removed `EphemMixin` in favor of astronomical functions (#302). - Added first day counting when computing working_days delta (#393), thx @Querdos. Incorporate changes from workalendar v5.2.3 (2019-07-11) - Fix Romania, make sure Easter and related holidays are calculated using the Orthodox calendar, thx to @KidkArolis (#389). v4.0.0 ====== Incorporate changes from workalendar v5.2.2. (2019-07-07) - **Deprecation Warning:** *Currently the registry returns `OrderedDict` objects when you're querying for regions or subregions. Expect that the next major release will preferrably return plain'ol' `dict` objects. If your scripts rely on the order of the objects returned, you'll have to sort them yourself.* - Fix Denmark, remove observances (remove Palm Sunday, Constitution Day, Christmas Eve and New Year's Eve) (#387, #386) Incorporate changes from workalendar v5.2.1 (2019-07-05) - Refactored the package building procedure, now linked to `make package` ; added a note about this target in the PR template (#366). - Fixed United Kingom's 2020 holidays ; The Early May Bank Holiday has been moved to May 8th to commemorate the 75th anniversary of the end of WWII (#381). Incorporate changes from workalendar v5.2.0 (2019-07-04) - New Calendar - Added JapanBank by @raybuhr (#379, #369). - Other changes - Added adjustments to 2019-2020 Japan calendar due to the coronation of a new emperor (#379). - Add a note about the fact that contributors should not change the version number in the changelog and/or the ``setup.py`` file (#380). Incorporate changes from workalendar v5.1.1 (2019-06-27) - Display missing lines in coverage report (#376). - Add "Europe Day" for Luxembourg (#377). Incorporate changes from workalendar v5.1.0 (2019-06-24) - New Calendar - Added Turkey by @tayyipgoren (#371). - Other changes - Change registry mechanism to avoid circular imports (#288). - Internal: Added a "Release" section to the Pull Request template. - Internal: Added advices on the Changelog entry in the Contributing document. - Bugfix: Fixing North Carolina shift rules when Christmas Day happens on Saturday (#232). - Documentation: rearrange country list in ``README.rst`` (sorting and fixing nested lists). - Documentation: Renamed and changed format of the "Contributing guidelines" document, now in Markdown (GFM variant), with a few fixes (#368). - Internal: remove coverage targets ; now coverage reports are displayed for each tox job, but they won't output classes with 100% coverage. Incorporate changes from workalendar v5.0.3 (2019-06-07) - Bugfix: Panama - Fixed incorrect independence from Spain date, thanks to @chopanpma (#361). Incorporate changes from workalendar v5.0.2 (2019-06-03) - Bugfix: Israel - Fixed incorrect Purim/Shushan Purim dates in jewish leap years, thx @orzarchi. This fix cancels the last (5.0.1) version, that will be deleted from PyPI. Incorporate changes from workalendar v5.0.1 (2019-06-03) - **WARNING** This version contains known bugs on Israel calendar. Please do not use it in production. - Bugfix: Israel - Fixed incorrect Purim/Shushan Purim dates in jewish leap years, thx @orzarchi. Incorporate changes from workalendar v5.0.0 (2019-05-24) - Major Changes & fixes - Dropped Python 3.4 support (#352). - Added Malaysia Thaipusam days for the year 2019 & 2020 - thx @burlak for the bug report (#354). - Fixed Deepavali dates for the year 2018 ; confirmed fixed dates that were set in the past. - Added calendars - Added Florida specific calendars: Florida Legal, Florida Circuit Courts, Miami-Dade (#216). Incorporate changes from workalendar v4.4.0 (2019-05-17) - **WARNING**: This release will be the last one to support Python 3.4, which has [reached its End of Life and has been retired](https://www.python.org/dev/peps/pep-0429/#release-schedule). Please upgrade. - Added calendar - Added California specific calendars: California Education, Berkeley, San Francisco, West Hollywood (#215). - Fixes - Added a few refactors and tests for Australia Capital Territory holiday named "Family & Community Day", that lasted from 2007 to 2017 (#25). - Added South African 2019 National Elections as holiday (#350), by @RichardOB. Incorporate changes from workalendar v4.3.1 (2019-05-03) - Bugfix: Update 2019 Labour Day Holidays for China as changed by government recently (2019-03-22), by @iamsk, and thanks to @ltyely for their patch (#345 & #347). Incorporate changes from workalendar v4.3.0 (2019-03-15) - New Calendar - Added Barbados by @ludsoft. - Fixes - Added isolated tests for shifting mechanics in USA calendars - previously untested (#335). - Added Berlin specific holidays (#340). - Added several one-off public holidays to UK calendar (#336). Incorporate changes from workalendar v4.2.0 (2019-02-21) - New calendars - Added several US territories and other specific calendars: - American Samoa territory (#218). - Chicago, Illinois (#220). - Guam territory (#219). - Suffolk County, Massachusetts (#222). - Added Cayman Islands, British Overseas Territory (#328) Incorporate changes from workalendar v4.1.0 (2019-02-07) - New calendars - **WARNING** Scotland (sub)calendars are highly experimental and because of their very puzzling rules, may be false. Please use them with care. - Added Scotland calendars, i.e. Scotland, Aberdeen, Angus, Arbroath, Ayr, Carnoustie & Monifieth, Clydebank, Dumfries & Galloway, Dundee, East Dunbartonshire, Edinburgh, Elgin, Falkirk, Fife, Galashiels, Glasgow, Hawick, Inverclyde, Inverness, Kilmarnock, Lochaber, Monifieth, North Lanarkshire, Paisley, Perth, Scottish Borders, South Lanarkshire, Stirling, and West Dunbartonshire (#31). - Bugfixes - Fixed United Kingdom bank holiday for 2002 and 2012, thx @ludsoft (#315). - Fix a small flake8 issue with wrong indentation (#319). - Fix Russia "Day of Unity" date, set to November 4th, thx @alexitkes for the bug report (#317). Incorporate changes from workalendar v4.0.0 (2019-01-24) - Solved the incompatibility between `pandas` latest version and Python 3.4. Upgraded travis distro to Xenial/16.04 LTS (#307). - Added instructions about the usage of the `iso_register` decorator in the pull-request template (#309). - New Calendars - Added New Zealand, by @johnguant (#306). - Added Paraguay calendar, following the work of @reichert (#268). - Added China calendar, by @iamsk (#304). - Added Israel, by @armona, @tsehori (#281). 3.0 === Incorporate changes from workalendar 3.2.1: - Added DEEPAVALI days for 2019 and 2020, thx @pvalenti (#282). - Fixed Germany Reformation Day miscalculation. Some German states include Reformation Day since the "beginning" ; in 2017, all states included Reformation Day as a holiday (500th anniversary of the Reformation) ; starting of 2018, 4 states added Reformation Day (#295). Incorporate changes from workalendar 3.2.0: - Removed dependency to `PyEphem`. This package was the "Python2-compatible" library to deal with the xephem system library. Now it's obsolete, so you don't need this dual-dependency handling, because `ephem` is compatible with Python 2 & Python 3 (#296). - Raise an exception when trying to use unsupported date/datetime types. Workalendar now only supports stdlib `date` & `datetime` (sub)types. See the `basic documentation `_ for more details (#294). Incorporate changes from workalendar 3.1.1: - Fixed ISO 3166-1 code for the `Slovenia` calendar (#291, thx @john-sandall). Incorporate changes from workalendar 3.1.0: - Added support for Python 3.7 (#283). - Fixed the `SouthAfrica` holidays calendar, taking into account the specs of holidays that vary over the periods. As a consequence, it cleaned up erroneous holidays that were duplicated in some years (#285). Thx to @surfer190 for his review & suggestions. - Bugfix for South Africa: disabled the possibility to compute holidays prior to the year 1910. - Renamed Madagascar test class name into `MadagascarTest` (#286). - Separated the coverage jobs from the pure tests. Their report output was disturbing in development mode, you had to scroll your way up to find eventual failing tests (#289). Incorporate changes from workalendar 3.0.0: Large work on global registry: refs (#13), (#96), (#257) & (#284). - Added Tests for Europe registry. - Revamped and cleaned up Europe countries. - Added the United States of America + States, American countries & sub-regions, African countries, Asian countries, Oceanian countries. - The global registry usage is documented. - Changed Canada namespace to `workalendar.america.canada`. - You don't have to declare a `name` properties for Calendar classes. It will be deducted from the docstring. - Changed the `registry.items()` mandatory argument name to `region_codes` for more readability. Incorporate changes from workalendar 2.6.0: - Added Angola, by @dvdmgl (#276) - Portugal - removed carnival from Portuguese holidays, restored missing holidays (#275) - Added All Souls Day to common (#274) - Allow the `add_working_days()` function to be provided a datetime, and returning a `date` (#270). - Added a `keep_datetime` option to keep the original type of the input argument for both ``add_working_days()`` and ``sub_working_days()`` functions (#270). - Fixed usage examples of ``get_first_weekday_after()`` docstring + in code (calendars and tests) ; do not use magic values, use MON, TUE, etc (#271). - Turned Changelog into a Markdown file (#272). - Added basic usage documentation, hosted by Github pages. - Added advanced usage documentation. Incorporate changes from workalendar 2.5.0: - Bugfix: deduplicate South Africa holidays that were emitted as duplicates (#265). - Add the `get_working_days_delta` method to the core calendar class (#260). Incorporate changes from workalendar 2.4.0: - Added Lithuania, by @landler (#254). - Added Russia, by @vanadium23 (#259). - Fixed shifting ANZAC day for Australia states (#249). - Renamed Australian state classes to actual state names(eg. AustraliaNewSouthWales to NewSouthWales). - Update ACT holidays (#251). - Fixing Federal Christmas Shift ; added a `include_veterans_day` flag to enable/disable Veteran's day on specific calendar - e.g. Mozilla's dedicated calendar (#242). - **Deprecation:** Dropped support for Python 3.3 (#245). - Fixed Travis-ci configuration for Python 3.5 and al (#252). - First step iteration on the "global registry" feature. European countries are now part of a registry loaded in the ``workalendar.registry`` module. Please use with care at the moment (#248). - Refactored Australia family and community day calculation (#244). 2.0 === Incorporate changes from workalendar 2.1.0: - Added Hong Kong, by @nedlowe (#235). - Splitted `africa.py` file into an `africa/` module (#236). - Added Alabama Counties - Baldwin County, Mobile County, Perry County. Refactored UnitedStates classes to have a parameter to include the "Mardi Gras" day (#214). - Added brazilian calendar to consider working days for bank transactions, by @fvlima (#238). Incorporate changes from workalendar 2.0.0: - Major refactor in the USA module. Each State is now an independant module, all of the Mixins were removed, all the possible corrections have been made, following the main Wikipedia page, and cross-checking with official sources when it was possible (#171). - Added District of Columbia in the USA module (#217). - Run tests with Python3.6 in CI (#210) - Small refactors / cleanups in the following calendars: Hungary, Iceland, Ireland, Latvia, Netherlands, Spain, Japan, Taiwan, Australia, Canada, USA (#209). - Various refactors for the Asia module, essentially centered around a more convenient Chinese New Year computation toolset (#202). - Refactoring the USA tests: using inheritance to test federal and state-based holidays using only one "Don't Repeat Yourself" codebase (#213). Incorporate changes from workalendar 1.3.0: - Added Singapore calendar, initiated by @nedlowe (#194 + #195). - Added Malaysia, by @gregyhj (#201). - Added Good Friday in the list of Hungarian holidays, as of the year 2017 (#203), thx to @mariusz-korzekwa for the bug report. - Assigned a minimal setuptools version, to avoid naughty ``DistributionNotFound`` exceptions with obsolete versions (#74). - Fixed a bug in Slovakia calendar, de-duplicated Christmas Day, that appeared twice (#205). - Fixed important bugs in the calendars of the following Brazilian cities: Vitória, Vila Velha, Cariacica, Guarapari and Serra - thx to Fernanda Gonçalves Rodrigues, who confirmed this issue raised by @Skippern (#199). Incorporate changes from workalendar 1.2.0: - Moved all the calendar of countries on the american continent in their own modules (#188). - Refactor base Calendar class get_weekend_days to use WEEKEND_DAYS more intelligently (#191 + #192). - Many additions to the Brazil and various states / cities. Were added: Acre, Alagoas, Amapá, Amazonas, Bahia, Ceará, Distrito Federal, Espírito Santo State, Goiás, Maranhão, Mato Grosso, Mato Grosso do Sul, Pará, Paraíba, Pernambuco, Piauí, Rio de Janeiro, Rio Grande do Norte, Rio Grande do Sul, Rondônia, Roraima, Santa Catarina, São Paulo, Sergipe, Tocantins, City of Vitória, City of Vila Velha, City of Cariacica, City of Guarapari and City of Serra (#187). - Added a ``good_friday_label`` class variable to ``ChristianMixin`` ; one can assign the right label to this holiday (#187). - Added a ``ash_wednesday_label`` class variable to ``ChristianMixin`` ; one can assign the right label to this holiday (#187). Incorporate changes from workalendar 1.1.0: - Added Cyprus. thx @gregn610 (#174). - Added Latvia. thx @gregn610 (#178). - Added Malta. thx @gregn610 (#179). - Added Romania. thx @gregn610 (#180). - Added Canton of Vaud (Switzerland) - @brutasse (#182). - Fixed January 2nd state holiday (#181). - Fixed Saxony repentance day for the year 2016. thx @Natim (#168). - Fixed Historical and one-off holidays for South Africa. thx @gregn610 (#173). - Minor PEP8 fixes (#186). Incorporate changes from workalendar 1.0.0: - Add Ireland. thx @gregn610 (#152). - Bugfix: New Year's Eve is not a holiday in Netherlands (#154). - Add Austria. thx @gregn610 (#153) - Add Bulgaria. thx @gregn610 (#156) - Add Croatia. thx @gregn610 (#157) Incorporate changes from workalendar 0.8.1: - Reformation Day is a national holiday in Germany, but only in 2017 (#150). 1.8 === Now tests are run using tox and releases are made automatically using Travis-CI deployment framework. Incorporate changes from workalendar 0.8.0: - Fix Czech Republic calendar - as of 2016, Good Friday has become a holiday (#148). Incorporate changes from workalendar 0.7.0: - Easter Sunday is a Brandenburg federate state holiday (#143), thx @uvchik. - Added Catalonia (#145), thx @ferranp. - Use `find_packages()` to fetch package directories in `setup.py` (#141, #144). - use py.test instead of nosetests for tests (#146). - cleanup: remove unused ``swiss.py`` file (#147). Incorporate changes from workalendar 0.6.1: - Added Estonia, thx to @landler (#134), - Europe-related modules being reorganized, thx to @Natim (#135), - Fixed King / Queen's day in Netherlands, thx to @PeterJacob (#138), - Added a pull-request template (#125), - Added a Makefile for various dev-related tasks -- installs, running tests, uploading to PyPI... (#133). 1.7.1 ===== - #7: Avoid crashing on import when installed as zip package. 1.7 === Incorporate changes from workalendar 0.5.0: - A new holiday has appeared in Japan as of 2016 (#131), thx @suhara for the report. Incorporate changes from workalendar 0.4.5: - Added Slovenia, thx to @ratek1 (#124). - Added Switzerland, thx to @sykaeh (#127). 1.6 === - #6: Remove observance shift for Sweden. - Use `jaraco skeleton `_ to maintain the project structure, adding automatic releases from continuous integration and bundled documentation. 1.5 === Incorporate changes from workalendar 0.4.3: - Added Denmark (#117). - Tiny fixes in the ``usa.py`` module (flake8 + typo) (#122) - Added datetime to date conversion in is_holiday() (#118) - Added function to get the holiday label by date (#120) - Moved from `novapost` to the `novafloss` organization, handling FLOSS projects in People Doc Inc. (#116) - Added Spain 2016 (#123) Incorporate changes from workalendar 0.4.2: - Added Luxembourg (#111) - Added Netherlands (#113) - Added Spain (#114) - Bugfix: fixed the name of the Pentecost for Sweden (#115) Incorporate changes from workalendar 0.4.1: - Added Portugal, thx to @borfast (#110). Incorporate changes from workalendar 0.4.0: - Added Colombia calendar, thx to @spalac24 - Added Slovakia calendar, thx to @Adman - Fixed the Boxing day & boxing day shift for Australia 1.4 === ``Calendar.get_observed_date`` now allows ``observance_shift`` to be a callable accepting the holiday and calendar and returning the observed date. ``Holiday`` supplies a ``get_nearest_weekday`` method suitable for locating the nearest weekday. - #5: USA Independence Day now honors the nearest weekday model. 1.3 === Incorporate these fixes from Workalendar 0.3: - ``delta`` argument for ``add_working_days()`` can be negative. added a ``sub_working_days()`` method that computes working days backwards. - BUGFIX: Renaming Showa Day. "ō is not romji" (#100) (thx @shinriyo) - BUGFIX: Belgian National Day title (#99) (thx @laulaz) 1.2.1 ===== Correct usage in example. 1.2 === Fixed issue #4 where Finland holidays were shifted but shouldn't have been. Calendars and Holidays may now specify observance_shift=None to signal no shift. Package can now be tested with pytest-runner by invoking ``python setup.py pytest``. 1.1.3 ===== Fix name of Finnish Independence Day. 1.1.2 ===== Fixed issues with packaging (disabled installation an zip egg and now use setuptools always). 1.1 === UnitedKingdom Calendar now uses indicated/observed Holidays. Includes these changes slated for workalendar 0.3: - BUGFIX: shifting UK boxing day if Christmas day falls on a Friday (shift to next Monday) (#95) 1.0 === Initial release of Calendra based on Workalendar 0.2. - Adds Holiday class per (#79). Adds support for giving holidays a more rich description and better resolution of observed versus indicated holidays. See the pull request for detail on the motivation and implementation. See the usa.UnitedStates calendar for example usage. Includes these changes slated for workalendar 0.3: - Germany calendar added, thx to @rndusr - Support building on systems where LANG=C (Ubuntu) (#92) - little improvement to directly return a tested value. calendra-7.9.0/README.md000066400000000000000000000150551457013633400145730ustar00rootroot00000000000000[![](https://img.shields.io/pypi/v/calendra.svg)](https://pypi.org/project/calendra) ![](https://img.shields.io/pypi/pyversions/calendra.svg) [![tests](https://github.com/jaraco/calendra/actions/workflows/main.yml/badge.svg)](https://github.com/jaraco/calendra/actions?query=workflow%3A%22tests%22) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![](https://readthedocs.org/projects/calendra/badge/?version=latest)](https://calendra.readthedocs.io/en/latest/?badge=latest) [![](https://img.shields.io/badge/skeleton-2024-informational)](https://blog.jaraco.com/skeleton) ## Overview Calendra is a Python module that offers classes able to handle calendars, list legal / religious holidays and gives working-day-related computation functions. ## History Calendra is a fork of [Workalendar](https://github.com/workalendar/workalendar) designed to be more extensible and introspectable, adding interfaces where [Workalendar is philosophically opposed for the sake of simplicity](https://github.com/workalendar/workalendar/pull/79). What can Calendra do that Workalendar cannot? - Provides descriptions for holidays for the "day indicated" for each Holiday (such as '3rd Monday in August'). - Keeps distinct the indicated and observed dates for Holidays, such that it's possible to determine on what day a given holiday is observed. - Allows the number of Holidays in a calendar year to be counted. - Consolidates observance logic in the core code rather than requiring each calendar implementation to implement its own. ## Status The project is stable and in production use. Calendra follows the principles of [semver](https://semver.org) for released verisons. If you spot any bug or wish to add a calendar, please refer to the [Contributing doc](https://peopledoc.github.io/workalendar/contributing.html). ## Usage sample ```python-repl >>> from datetime import date >>> from calendra.europe import France >>> cal = France() >>> cal.holidays(2012) [(datetime.date(2012, 1, 1), 'New year'), (datetime.date(2012, 4, 9), 'Easter Monday'), (datetime.date(2012, 5, 1), 'Labour Day'), (datetime.date(2012, 5, 8), 'Victory in Europe Day'), (datetime.date(2012, 5, 17), 'Ascension Day'), (datetime.date(2012, 5, 28), 'Whit Monday'), (datetime.date(2012, 7, 14), 'Bastille Day'), (datetime.date(2012, 8, 15), 'Assumption of Mary to Heaven'), (datetime.date(2012, 11, 1), "All Saints' Day"), (datetime.date(2012, 11, 11), 'Armistice Day'), (datetime.date(2012, 12, 25), 'Christmas')] >>> cal.is_working_day(date(2012, 12, 25)) # it's Christmas False >>> cal.is_working_day(date(2012, 12, 30)) # it's Sunday False >>> cal.is_working_day(date(2012, 12, 26)) True >>> cal.add_working_days(date(2012, 12, 23), 5) # 5 working days after Xmas datetime.date(2012, 12, 31) ``` For a more complete documentation and advanced usage, go to [the official workalendar documentation](https://workalendar.github.io/workalendar). ## External dependencies Calendra has been tested on the Python versions declared in setup.cfg. ## Tests To run test, just install tox with `pip install tox` and run `tox` from the command line. ## Available Calendars ### Europe - Austria - Belarus - Belgium - Bulgaria - Cayman Islands - Croatia - Cyprus - Czech Republic - Denmark - Estonia - European Central Bank - Finland - France - France (Alsace / Moselle) - Georgia - Germany - Greece - Guernsey - Hungary - Iceland - Ireland - Italy - Latvia - Lithuania - Luxembourg - Malta - Monaco - Netherlands (optionally with school holidays and carnival) - Norway - Poland - Portugal - Romania - Russia - Serbia - Slovakia - Slovenia - Spain (Andalusia, Aragon, Castile and León, Castilla-La Mancha, Canary Islands, Extremadura, Galicia, Balearic Islands, La Rioja, Community of Madrid, Murcia, Navarre, Asturias, Basque Country, Cantabria, Valencian Community) - Sweden - Switzerland (Aargau, Appenzell Innerrhoden, Appenzell Ausserrhoden, Bern, Basel-Landschaft, Basel-Stadt, Fribourg, Geneva, Glarus, Graubünden, Jura, Luzern, Neuchâtel, Nidwalden, Obwalden, St. Gallen, Schaffhausen, Solothurn, Schwyz, Thurgau, Ticino, Uri, Vaud, Valais, Zug, Zurich) - Turkey - Ukraine - United Kingdom (incl. Northern Ireland, Scotland and all its territories) ### America - Argentina - Barbados - Brazil (all states, cities and for bank transactions, except the city of Viana) - Canada (including provincial and territory holidays) - Chile - Colombia - El Salvador - Mexico - Panama - Paraguay - United States of America - State holidays for all the 50 States - American Samoa - Chicago, Illinois - Guam - Suffolk County, Massachusetts - California Education, Berkeley, San Francisco, West Hollywood - Florida Legal and Florida Circuit Courts, Miami-Dade - Federal Reserve System ### Asia - China - Hong Kong - Israel - Japan - JapanBank - Kazakhstan - Malaysia - Philippines - Qatar - Singapore - South Korea - Taiwan ### Oceania - Australia (incl. its different states) - Marshall Islands - New Zealand ### Africa - Algeria - Angola - Benin - Ivory Coast - Kenya - Madagascar - Mozambique - Nigeria - São Tomé - South Africa - Tunisia And more to come (I hope!) ## Caveats Please take note that some calendars are not 100% accurate. The most common example is the Islamic calendar, where some computed holidays are not exactly on the same official day decided by religious authorities, and this may vary country by country. Whenever it's possible, try to adjust your results with the official data provided by the adequate authorities. Some countries have some holidays based on ephemerids and equinoxes. Those are computed for the previous and next 30 years to prevent big computations and dependencies. ## Contributing Please read our [contributing.md](https://github.com/workalendar/workalendar/blob/master/docs/contributing.md) document to discover how you can contribute to `workalendar`. Pull-requests are very welcome. ## History This project was born in 2013, as an answer to the question "how do we calculate *this date + 5 working days*?". It was a use-case for [PeopleDoc](https://www.people-doc.fr/), in their ticketing application, for calculating SLAs. And it began as a small open-source library, for France and the USA at first. Thanks to PeopleDoc, this project grew and eventually became a world-wide library, with the help of dozens of contributors. As of June 2021, this project has moved to its own organization. ## License This library is published under the terms of the MIT License. Please check the LICENSE file for more details. calendra-7.9.0/calendra/000077500000000000000000000000001457013633400150575ustar00rootroot00000000000000calendra-7.9.0/calendra/__init__.py000066400000000000000000000003061457013633400171670ustar00rootroot00000000000000try: import importlib.metadata as metadata except ImportError: import importlib_metadata as metadata #: Module version, as defined in PEP-0396. __version__ = metadata.version(__package__) calendra-7.9.0/calendra/africa/000077500000000000000000000000001457013633400163045ustar00rootroot00000000000000calendra-7.9.0/calendra/africa/__init__.py000066400000000000000000000010441457013633400204140ustar00rootroot00000000000000from .algeria import Algeria from .benin import Benin from .ivory_coast import IvoryCoast from .kenya import Kenya from .madagascar import Madagascar from .sao_tome import SaoTomeAndPrincipe from .south_africa import SouthAfrica from .angola import Angola from .mozambique import Mozambique from .nigeria import Nigeria from .tunisia import Tunisia __all__ = ( 'Algeria', 'Benin', 'IvoryCoast', 'Kenya', 'Madagascar', 'SaoTomeAndPrincipe', 'SouthAfrica', 'Angola', 'Mozambique', 'Nigeria', 'Tunisia', ) calendra-7.9.0/calendra/africa/algeria.py000066400000000000000000000011311457013633400202560ustar00rootroot00000000000000from ..core import IslamicCalendar from ..registry_tools import iso_register @iso_register('DZ') class Algeria(IslamicCalendar): "Algeria" # Civil holidays include_labour_day = True # Islamic holidays include_prophet_birthday = True include_eid_al_fitr = True include_day_of_sacrifice = True include_islamic_new_year = True FIXED_HOLIDAYS = IslamicCalendar.FIXED_HOLIDAYS + ( (7, 5, "Independence Day"), (11, 1, "Anniversary of the revolution"), ) ISLAMIC_HOLIDAYS = IslamicCalendar.ISLAMIC_HOLIDAYS + ( (1, 10, "Ashura"), ) calendra-7.9.0/calendra/africa/angola.py000066400000000000000000000014131457013633400201160ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('AO') class Angola(WesternCalendar): "Angola" # Civil holiday include_labour_day = True labour_day_label = "Dia Internacional do Trabalhador" # Christian holidays include_fat_tuesday = True fat_tuesday_label = "Dia de Carnaval" include_good_friday = True include_easter_sunday = True include_christmas = True include_all_souls = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 4, "Dia do Inicio da Luta Armada"), (3, 8, "Dia Internacional da Mulher"), (4, 4, "Dia da Paz"), (9, 17, "Dia do Fundador da Nação e do Herói Nacional"), (11, 11, "Dia da Independência Nacional"), ) calendra-7.9.0/calendra/africa/benin.py000066400000000000000000000015671457013633400177620ustar00rootroot00000000000000from ..core import IslamoWesternCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register('BJ') class Benin(IslamoWesternCalendar): "Benin" # Civil holidays include_labour_day = True # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_assumption = True include_all_saints = True # Islamic holidays include_prophet_birthday = True include_eid_al_fitr = True include_day_of_sacrifice = True include_day_of_sacrifice_label = "Tabaski" FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + ( (1, 10, "Traditional Day"), (8, 1, "Independence Day"), (10, 26, "Armed Forces Day"), (11, 30, "National Day"), ) # Explicitly assign these WE days, Benin has adopted the western workweek WEEKEND_DAYS = (SAT, SUN) calendra-7.9.0/calendra/africa/ivory_coast.py000066400000000000000000000014771457013633400212300ustar00rootroot00000000000000from ..core import IslamoWesternCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register('CI') class IvoryCoast(IslamoWesternCalendar): "Ivory Coast" # Civil holidays include_labour_day = True # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_assumption = True include_all_saints = True # Islamic holidays include_day_after_prophet_birthday = True include_eid_al_fitr = True include_day_of_sacrifice = True include_day_of_sacrifice_label = "Feast of the Sacrifice" FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + ( (8, 7, "Independence Day"), (11, 15, "National Peace Day"), ) # Ivory Coast has adopted the "western" workweek. WEEKEND_DAYS = (SAT, SUN) calendra-7.9.0/calendra/africa/kenya.py000066400000000000000000000045371457013633400177760ustar00rootroot00000000000000from copy import copy from datetime import timedelta, date from ..core import IslamoWesternCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register('KE') class Kenya(IslamoWesternCalendar): "Kenya" # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_easter_monday = True # Islamic holidays include_eid_al_fitr = True include_day_of_sacrifice = True shift_sunday_holidays = True # Explicitly assign these WE days, Kenya has adopted the western workweek WEEKEND_DAYS = (SAT, SUN) FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + ( (6, 1, "Madaraka Day"), (10, 20, "Mashujaa Day"), (12, 12, "Jamhuri Day"), (12, 31, "New Years Eve"), ) def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if year >= 2020: days.append((date(year, 2, 11), 'Moi Memorial Day')) # Moi Day renamed huduma_day_label = "Moi Day" if year >= 2020: huduma_day_label = "Huduma Day" days.append((date(year, 10, 10), huduma_day_label)) # Boxing day renamed boxing_day_label = "Boxing Day" if year >= 2020: boxing_day_label = "Utamaduni Day" days.append((date(year, 12, 26), boxing_day_label)) return days def get_shifted_holidays(self, dates): """ Taking a list of existing holidays, yield a list of 'shifted' days if the holiday falls on SUN, excluding the Islamic holidays. """ for holiday, label in dates: if (holiday.weekday() == SUN and label != self.eid_al_fitr_label and label != self.day_of_sacrifice_label): yield ( holiday + timedelta(days=1), f'{label} Shift' ) def get_calendar_holidays(self, year): """ Take into account the eventual shift to the next MON if any holiday falls on SUN. """ # Unshifted days are here: days = super().get_calendar_holidays(year) if self.shift_sunday_holidays: days_to_inspect = copy(days) for day_shifted in self.get_shifted_holidays(days_to_inspect): days.append(day_shifted) return days calendra-7.9.0/calendra/africa/madagascar.py000066400000000000000000000010001457013633400207300ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('MG') class Madagascar(WesternCalendar): "Madagascar" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (3, 29, "Martyrs' Day"), (6, 26, "Independence Day"), ) # Civil holidays include_labour_day = True # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_assumption = True include_all_saints = True calendra-7.9.0/calendra/africa/mozambique.py000066400000000000000000000011151457013633400210250ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('MZ') class Mozambique(WesternCalendar): "Mozambique" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 3, "Mozambican Heroes' Day"), (4, 7, "Mozambican Women's Day"), (6, 25, "Independence Day"), (9, 7, "Victory Day"), (9, 25, "Armed Forces Day"), (10, 4, "Peace And Reconciliation Day"), ) # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_christmas = True calendra-7.9.0/calendra/africa/nigeria.py000066400000000000000000000023711457013633400202770ustar00rootroot00000000000000from datetime import date from ..core import IslamoWesternCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register("NG") class Nigeria(IslamoWesternCalendar): "Nigeria" # Civil holidays include_labour_day = True labour_day_label = "Workers' Day" # Christian holidays include_good_friday = True include_easter_monday = True include_boxing_day = True # Islamic holidays include_eid_al_fitr = True include_day_of_sacrifice = True shift_sunday_holidays = True shift_new_years_day = True # Explicitly assign these WE days, Nigeria has adopted the western workweek WEEKEND_DAYS = (SAT, SUN) FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + ( (10, 1, "Independence Day"), ) def get_fixed_holidays(self, year): """Get fixed holidays. Args: year (int): Year Returns: tuple: Tuple of date and label """ days = super().get_fixed_holidays(year) democracy_day_label = "Democracy Day" if 2000 <= year < 2018: days.append((date(year, 5, 29), democracy_day_label)) if year >= 2018: days.append((date(year, 6, 12), democracy_day_label)) return days calendra-7.9.0/calendra/africa/sao_tome.py000066400000000000000000000010161457013633400204620ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('ST') class SaoTomeAndPrincipe(WesternCalendar): "São Tomé and Príncipe" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 3, "Martyr's Day"), (7, 12, "Independence Day"), (9, 6, "Armed Forces Day"), (9, 30, "Agricultural Reform Day"), (12, 21, "São Tomé Day"), ) # Civil holidays include_labour_day = True # Christian holidays include_all_saints = True calendra-7.9.0/calendra/africa/south_africa.py000066400000000000000000000126001457013633400213240ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, MON, FRI from ..exceptions import CalendarError from ..registry_tools import iso_register @iso_register('ZA') class SouthAfrica(WesternCalendar): "South Africa" include_good_friday = True include_christmas = True def holidays(self, year=None): if year < 1910: raise CalendarError("It's not possible to compute holidays prior" " to 1910 for South Africa.") return super().holidays(year) def get_easter_monday_or_family_day(self, year): if year < 1980: label = "Easter Monday" else: label = "Family Day" return self.get_easter_monday(year), label def get_fixed_holidays(self, year): # noqa: C901 days = super().get_fixed_holidays(year) if year >= 1990: days.append((date(year, 3, 21), 'Human Rights Day')) # Van Riebeeck's day & Founder's day if year >= 1952 and year <= 1973: days.append((date(year, 4, 6), "Van Riebeeck's Day")) if year >= 1980 and year <= 1994: days.append((date(year, 4, 6), "Founder's Day")) if year >= 1994: days.append((date(year, 4, 27), "Freedom Day")) # Workers day established in 1995 to May 1st if year >= 1995: days.append((date(year, 5, 1), "Workers' Day")) if year <= 1951: days.append((date(year, 5, 24), "Victoria Day / Empire Day")) # May 31st: Union Day & Republic Day if year <= 1960: days.append((date(year, 5, 31), "Union Day")) elif year <= 1993: days.append((date(year, 5, 31), "Republic Day")) if year >= 1995: days.append((date(year, 6, 16), "Youth Day")) if year > 1960 and year <= 1973: days.append((date(year, 7, 10), "Family Day")) if year >= 1995: days.append((date(year, 8, 9), "National Women's Day")) days.append((date(year, 9, 24), "Heritage Day")) if year >= 1952 and year <= 1993: days.append((date(year, 10, 10), "Kruger Day")) if year <= 1951: december_16th_label = "Dingaan's Day" elif 1952 <= year <= 1979: december_16th_label = "Day of the Covenant" elif 1980 <= year <= 1994: december_16th_label = "Day of the Vow" else: december_16th_label = "Day of Reconciliation" days.append((date(year, 12, 16), december_16th_label)) # Boxing day renamed boxing_day_label = "Boxing Day" if year >= 1980: boxing_day_label = "Day of Goodwill" days.append((date(year, 12, 26), boxing_day_label)) return days def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_easter_monday_or_family_day(year)) # Workers day was first friday of may 1987-1989 if 1987 <= year <= 1989: days.append( (self.get_nth_weekday_in_month(year, 5, FRI), "Workers' Day") ) if year <= 1993: days.append((self.get_ascension_thursday(year), "Ascension Day")) # Queen's Birthday on the 2nd Monday of july 1952-1960 if 1952 <= year <= 1960: days.append(( self.get_nth_weekday_in_month(year, 7, MON, 2), "Queen's Birthday" )) # King's Birthday on the first Monday of August 1910-1951 if 1910 <= year <= 1951: days.append(( self.get_nth_weekday_in_month(year, 8, MON), "King's Birthday" )) if year >= 1952 and year <= 1979: days.append((self.get_nth_weekday_in_month(year, 9, MON), "Settlers' Day")) return days def get_calendar_holidays(self, year): # noqa: C901 days = super().get_calendar_holidays(year) # Other one-offs. Don't shift these if year == 1999: days.append((date(year, 6, 2), "National Elections")) days.append((date(year, 12, 31), "Y2K")) if year == 2000: # 2 January 2000 public holidays to accommodate the Y2K changeover, # 3 January 2000 because the previous holiday was a Sunday days.append((date(year, 1, 2), "Y2K")) days.append((date(year, 1, 3), "Y2K")) if year == 2001: days.append((date(year, 1, 2), "Y2K")) if year == 2004: days.append((date(year, 4, 14), "National Elections")) if year == 2006: days.append((date(year, 3, 1), "Local Elections")) if year == 2008: # 2 May 2008 was declared a public holiday when Human Rights Day # and Good Friday coincided on 21 March 2008 days.append((date(year, 5, 2), "Special Human Rights")) if year == 2009: days.append((date(year, 4, 22), "National Elections")) if year == 2011: days.append((date(year, 5, 18), "Local Elections")) days.append((date(year, 12, 27), "Special Day of Goodwill")) if year == 2014: days.append((date(year, 5, 7), "National Elections")) if year == 2016: days.append((date(year, 8, 3), "Local Elections")) if year == 2019: days.append((date(year, 5, 8), "National Elections")) return days calendra-7.9.0/calendra/africa/tunisia.py000066400000000000000000000024071457013633400203350ustar00rootroot00000000000000from datetime import date from ..core import IslamicCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register('TN') class Tunisia(IslamicCalendar): "Tunisia" # Civil holidays include_labour_day = True # Islamic holidays include_prophet_birthday = True include_eid_al_fitr = True length_eid_al_fitr = 2 include_day_of_sacrifice = True length_eid_al_adha = 4 include_islamic_new_year = True FIXED_HOLIDAYS = IslamicCalendar.FIXED_HOLIDAYS + ( (3, 20, "Independence Day"), (7, 25, "Republic Day"), (4, 9, "Martyrs' Day"), (8, 13, "Women's Day"), (10, 15, "Evacuation Day") ) # Tunisia has adopted the "western" workweek. WEEKEND_DAYS = (SAT, SUN) def get_fixed_holidays(self, year): """Get fixed holidays. Args: year (int): Year Returns: tuple: Tuple of date and label """ days = super().get_fixed_holidays(year) revolution_day_label = "Revolution Day" if 2011 < year <= 2020: days.append((date(year, 1, 14), revolution_day_label)) if year >= 2021: days.append((date(year, 12, 17), revolution_day_label)) return days calendra-7.9.0/calendra/america/000077500000000000000000000000001457013633400164605ustar00rootroot00000000000000calendra-7.9.0/calendra/america/__init__.py000066400000000000000000000067761457013633400206110ustar00rootroot00000000000000from .barbados import Barbados from .brazil import ( Brazil, BrazilAcre, BrazilAlagoas, BrazilAmapa, BrazilAmazonas, BrazilBahia, BrazilCeara, BrazilDistritoFederal, BrazilEspiritoSanto, BrazilGoias, BrazilMaranhao, BrazilMinasGerais, BrazilMatoGrosso, BrazilMatoGrossoDoSul, BrazilPara, BrazilParaiba, BrazilPernambuco, BrazilPiaui, BrazilParana, BrazilRioDeJaneiro, BrazilRioGrandeDoNorte, BrazilRioGrandeDoSul, BrazilRondonia, BrazilRoraima, BrazilSantaCatarina, BrazilSaoPauloState, BrazilSaoPauloCity, BrazilSergipe, BrazilTocantins, BrazilVitoriaCity, BrazilVilaVelhaCity, BrazilCariacicaCity, BrazilGuarapariCity, BrazilSerraCity, BrazilRioBrancoCity, BrazilMaceioCity, BrazilManausCity, BrazilMacapaCity, BrazilSalvadorCity, BrazilFortalezaCity, BrazilGoianiaCity, BrazilBeloHorizonteCity, BrazilCampoGrandeCity, BrazilCuiabaCity, BrazilBelemCity, BrazilJoaoPessoaCity, BrazilRecifeCity, BrazilTeresinaCity, BrazilCuritibaCity, BrazilNatalCity, BrazilPortoVelhoCity, BrazilBoaVistaCity, BrazilPortoAlegreCity, BrazilChapecoCity, BrazilFlorianopolisCity, BrazilJoinvilleCity, BrazilAracajuCity, BrazilSorocabaCity, BrazilPalmasCity, BrazilBankCalendar ) from .canada import ( Canada, Ontario, Quebec, BritishColumbia, Alberta, Saskatchewan, Manitoba, NewBrunswick, NovaScotia, PrinceEdwardIsland, Newfoundland, Yukon, NorthwestTerritories, Nunavut ) from .chile import Chile from .colombia import Colombia from .mexico import Mexico from .panama import Panama from .paraguay import Paraguay from .argentina import Argentina from .el_salvador import ElSalvador __all__ = ( # Brazil & its states. 'Brazil', 'BrazilAcre', 'BrazilAlagoas', 'BrazilAmapa', 'BrazilAmazonas', 'BrazilBahia', 'BrazilCeara', 'BrazilDistritoFederal', 'BrazilEspiritoSanto', 'BrazilGoias', 'BrazilMaranhao', 'BrazilMinasGerais', 'BrazilMatoGrosso', 'BrazilMatoGrossoDoSul', 'BrazilPara', 'BrazilParaiba', 'BrazilPernambuco', 'BrazilPiaui', 'BrazilParana', 'BrazilRioDeJaneiro', 'BrazilRioGrandeDoNorte', 'BrazilRioGrandeDoSul', 'BrazilRondonia', 'BrazilRoraima', 'BrazilSantaCatarina', 'BrazilSaoPauloState', 'BrazilSaoPauloCity', 'BrazilSergipe', 'BrazilTocantins', 'BrazilVitoriaCity', 'BrazilVilaVelhaCity', 'BrazilCariacicaCity', 'BrazilGuarapariCity', 'BrazilSerraCity', 'BrazilBankCalendar', 'BrazilRioBrancoCity', 'BrazilMaceioCity', 'BrazilManausCity', 'BrazilMacapaCity', 'BrazilSalvadorCity', 'BrazilFortalezaCity', 'BrazilGoianiaCity', 'BrazilBeloHorizonteCity', 'BrazilCampoGrandeCity', 'BrazilCuiabaCity', 'BrazilBelemCity', 'BrazilJoaoPessoaCity', 'BrazilRecifeCity', 'BrazilTeresinaCity', 'BrazilCuritibaCity', 'BrazilNatalCity', 'BrazilPortoVelhoCity', 'BrazilBoaVistaCity', 'BrazilPortoAlegreCity', 'BrazilChapecoCity', 'BrazilFlorianopolisCity', 'BrazilJoinvilleCity', 'BrazilAracajuCity', 'BrazilSorocabaCity', 'BrazilPalmasCity', # Canada 'Canada', 'Ontario', 'Quebec', 'BritishColumbia', 'Alberta', 'Saskatchewan', 'Manitoba', 'NewBrunswick', 'NovaScotia', 'PrinceEdwardIsland', 'Newfoundland', 'Yukon', 'NorthwestTerritories', 'Nunavut', # Other american countries 'Barbados', 'Chile', 'Colombia', 'Mexico', 'Panama', 'Paraguay', 'Argentina', 'ElSalvador', ) calendra-7.9.0/calendra/america/argentina.py000066400000000000000000000111341457013633400210020ustar00rootroot00000000000000from datetime import timedelta, date from ..core import WesternCalendar, MON, TUE, WED, THU, FRI, SAT from ..registry_tools import iso_register @iso_register('AR') class Argentina(WesternCalendar): 'Argentina' # Civil holidays include_labour_day = True labour_day_label = "Día del Trabajador" # Christian holidays include_fat_tuesday = True fat_tuesday_label = "Carnival" include_good_friday = True include_easter_saturday = True include_easter_sunday = True include_christmas = True include_immaculate_conception = True immaculate_conception_label = "Día de la Inmaculada Concepción de María" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (3, 24, "Día Nacional de la Memoria por la Verdad y la Justicia"), (5, 25, "Día de la Revolución de Mayo"), (6, 20, "Día Paso a la Inmortalidad del General Manuel Belgrano"), (7, 9, "Día de la Independencia"), ) def get_general_guemes_day(self, year): """ Día Paso a la Inmortalidad del General Martín Miguel de Güemes. Happens on June 17th, except: * if it happens on a THU, it's shifted to the next MON. * if it happens on a WED, it's shifted to the MON before this date. """ general_guemes_day = date(year, 6, 17) if general_guemes_day.weekday() == THU: general_guemes_day = Argentina.get_first_weekday_after( date(year, 6, 17), MON) elif general_guemes_day.weekday() == WED: # Monday of the same week general_guemes_day = general_guemes_day - timedelta(days=2) else: general_guemes_day return ( general_guemes_day, "Día Paso a la Inmortalidad del General Martín Miguel de Güemes" ) def get_general_martin_day(self, year): """ Día Paso a la Inmortalidad del Gral. José de San Martín Third MON of August. """ general_martin_day = Argentina.get_nth_weekday_in_month( year, 8, MON, 3 ) return ( general_martin_day, "Día Paso a la Inmortalidad del Gral. José de San Martín" ) def get_soberania_day(self, year): """ Día de la Soberanía Nacional Happens on the 3rd MON of November after the first Friday. """ first_friday_november = Argentina.get_nth_weekday_in_month( year, 11, FRI, 1 ) soberania_day = Argentina.get_nth_weekday_in_month( year, 11, MON, n=3, start=first_friday_november ) return soberania_day, "Día de la Soberanía Nacional" def get_diversidad_day(self, year): """ Día del Respeto a la Diversidad Cultural The pivot date is the 12th of October. * If it happens on a TUE, it's shifter on the 11th of Oct. * If it happens on a WED, THU, FRI or SAT, it's shifted on the first MON after this date. * Else, it's on the 12th of October. """ diversidad_day = date(year, 10, 12) if (diversidad_day.weekday() == WED or diversidad_day.weekday() == THU or diversidad_day.weekday() == FRI or diversidad_day.weekday() == SAT): diversidad_day = Argentina.get_first_weekday_after( date(year, 10, 12), MON ) elif diversidad_day.weekday() == TUE: diversidad_day = diversidad_day - timedelta(days=1) else: diversidad_day return (diversidad_day, "Día del Respeto a la Diversidad Cultural") def get_malvinas_day(self, year): """ Día de las Malvinas In honour of the Veterans and the Fallen of the Malvinas war. https://en.wikipedia.org/wiki/Malvinas_Day In 2020, it was shifted to March 31st because of the coronavirus crisis. """ label = "Día del Veterano y de los Caídos en la Guerra de Malvinas" if year == 2020: day = date(year, 3, 31) else: day = date(year, 4, 2) return day, label def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_easter_sunday(year) - timedelta(days=48), "Carnival Lunes")) days.extend([ self.get_malvinas_day(year), self.get_general_guemes_day(year), self.get_general_martin_day(year), self.get_soberania_day(year), self.get_diversidad_day(year) ]) return days calendra-7.9.0/calendra/america/barbados.py000066400000000000000000000047501457013633400206150ustar00rootroot00000000000000from copy import copy from datetime import date, timedelta from ..core import MON, SUN, WesternCalendar from ..registry_tools import iso_register @iso_register("BB") class Barbados(WesternCalendar): "Barbados" # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_easter_sunday = True include_easter_monday = True include_whit_monday = True non_computable_holiday_dict = { 2016: [(date(2016, 12, 27), "Public Holiday")], 2021: [ (date(2021, 1, 4), "Public Holiday"), (date(2021, 1, 5), "Public Holiday"), ], } # All holiday are shifted if on a Sunday FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 21, "Errol Barrow Day"), (4, 28, "National Heroes Day"), (11, 30, "Independance Day"), (12, 26, "Boxing Day"), # Not the same as UK Boxing Day ) def get_kadooment_day(self, year): """ First Monday of August. """ return (Barbados.get_nth_weekday_in_month(year, 8, MON), "Kadooment Day") def get_emancipation_day(self, year): emancipation_day = date(year, 8, 1) if emancipation_day.weekday() == SUN: emancipation_day += timedelta(days=1) kadooment_day = self.get_kadooment_day(year) if emancipation_day == kadooment_day[0]: emancipation_day += timedelta(days=1) return (emancipation_day, "Emancipation Day") def get_variable_days(self, year): """ Return variable holidays of the Barbados calendar. """ days = super().get_variable_days(year) days.append(self.get_kadooment_day(year)) days.append(self.get_emancipation_day(year)) non_computable = self.non_computable_holiday(year) if non_computable: days.extend(non_computable) return days def non_computable_holiday(self, year): non_computable = self.non_computable_holiday_dict.get(year, None) return non_computable def get_fixed_holidays(self, year): """ Return fixed holidays of the Barbados calendar. A shift day is appended if a fixed holiday happens on SUN. """ days = super().get_fixed_holidays(year) days_to_shift = copy(days) for day, label in days_to_shift: if day.weekday() == SUN: days.append((day + timedelta(days=1), f"{label} (shifted)")) return days calendra-7.9.0/calendra/america/brazil.py000066400000000000000000000476201457013633400203260ustar00rootroot00000000000000from datetime import timedelta, date from ..core import WesternCalendar, MON, SAT, SUN from ..registry_tools import iso_register @iso_register('BR') class Brazil(WesternCalendar): "Brazil" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (4, 21, "Tiradentes' Day"), (9, 7, "Independence Day"), (10, 12, "Our Lady of Aparecida"), (11, 2, "All Souls' Day"), (11, 15, "Republic Day"), ) include_sao_jose = False sao_jose_label = "São José" include_sao_pedro = False sao_pedro_label = "São Pedro" include_sao_joao = False sao_joao_label = "São João" # Civil holidays include_labour_day = True include_servidor_publico = False servidor_publico_label = "Dia do Servidor Público" # Consciência Negra day include_consciencia_negra = False # There are two dates for the Consciência Negra day # The most common is November, 20th consciencia_negra_day = (11, 20) consciencia_negra_label = "Consciência Negra" # Christian holidays include_easter_sunday = True # Dia de Nossa Senhora da Conceição is the Immaculate Conception. include_immaculate_conception = False immaculate_conception_label = "Dia de Nossa Senhora da Conceição" def get_variable_days(self, year): days = super().get_variable_days(year) if self.include_sao_jose: days.append((date(year, 3, 19), self.sao_jose_label)) if self.include_sao_pedro: days.append((date(year, 6, 29), self.sao_pedro_label)) if self.include_sao_joao: days.append((date(year, 6, 24), self.sao_joao_label)) if self.include_servidor_publico: days.append((date(year, 10, 28), self.servidor_publico_label)) if self.include_consciencia_negra: month, day = self.consciencia_negra_day days.append( (date(year, month, day), self.consciencia_negra_label) ) return days @iso_register('BR-AC') class BrazilAcre(Brazil): "Brazil Acre State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (1, 23, "Dia do evangélico"), (6, 15, "Aniversário do Acre"), (9, 5, "Dia da Amazônia"), (11, 17, "Assinatura do Tratado de Petrópolis"), (8, 6, "Início da Revolução Acreana"), ) @iso_register('BR-AL') class BrazilAlagoas(Brazil): "Brazil Alagoas State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (9, 16, "Emancipação política de Alagoas"), ) include_sao_pedro = True include_sao_joao = True include_consciencia_negra = True @iso_register('BR-AP') class BrazilAmapa(Brazil): "Brazil Amapá State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (7, 25, "São Tiago"), (10, 5, "Criação do estado"), (9, 13, "Aniversário da Amapá"), ) include_sao_jose = True sao_jose_label = "Dia de São José" include_consciencia_negra = True @iso_register('BR-AM') class BrazilAmazonas(Brazil): "Brazil Amazonas State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (9, 5, "Elevação do Amazonas á categoria de província"), ) include_consciencia_negra = True include_immaculate_conception = True @iso_register('BR-BA') class BrazilBahia(Brazil): "Brazil Bahia State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (7, 2, "Independência da Bahia"), ) @iso_register('BR-CE') class BrazilCeara(Brazil): "Brazil Ceará State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (3, 23, "Data Manga do Ceará"), (3, 25, "Aniversário do Ceará"), ) include_sao_jose = True @iso_register('BR-DF') class BrazilDistritoFederal(Brazil): "Brazil Distrito Federal State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (4, 21, "Fundação de Brasília"), (11, 30, "Dia do Evangélico"), ) @iso_register('BR-ES') class BrazilEspiritoSanto(Brazil): "Brazil Espírito Santo State" include_servidor_publico = True @iso_register('BR-GO') class BrazilGoias(Brazil): "Brazil Goiás State" include_servidor_publico = True @iso_register('BR-MA') class BrazilMaranhao(Brazil): "Brazil Maranhão State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (7, 28, "Adesão do Maranhão á independência do Brasil"), ) include_immaculate_conception = True @iso_register('BR-MG') class BrazilMinasGerais(Brazil): "Brasil Minas Gerais State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (4, 21, "Aniversário de Minas Gerais"), ) @iso_register('BR-MT') class BrazilMatoGrosso(Brazil): "Brazil Mato Grosso State" include_consciencia_negra = True consciencia_negra_day = (11, 29) @iso_register('BR-MS') class BrazilMatoGrossoDoSul(Brazil): "Brazil Mato Grosso do Sul State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (10, 11, "Criação do estado"), ) @iso_register('BR-PA') class BrazilPara(Brazil): "Brazil Pará State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (8, 15, "Adesão do Grão-Pará á independência do Brasil"), ) include_immaculate_conception = True @iso_register('BR-PB') class BrazilParaiba(Brazil): "Brazil Paraíba State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (8, 5, "Fundação do Estado"), (7, 26, "Homenagem à memória do ex-presidente João Pessoa"), ) @iso_register('BR-PE') class BrazilPernambuco(Brazil): "Brazil Pernambuco State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (6, 3, "Revolução Pernambucana de 1817"), ) include_sao_joao = True @iso_register('BR-PI') class BrazilPiaui(Brazil): "Brazil Piauí State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (3, 13, "Dia da Batalha do Jenipapo"), (10, 19, "Dia do Piauí"), ) @iso_register('BR-PR') class BrazilParana(Brazil): "Brazil Paraná State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (12, 19, "Aniversário do Paraná"), ) @iso_register('BR-RJ') class BrazilRioDeJaneiro(Brazil): "Brazil Rio de Janeiro State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (4, 23, "Dia de São Jorge"), (3, 1, "Aniversário da Cidade do Rio de Janeiro"), ) include_fat_tuesday = True fat_tuesday_label = "Carnaval" include_servidor_publico = True servidor_publico_label = "Dia do Funcionário Público" include_consciencia_negra = True consciencia_negra_label = "Dia da Consciência Negra" include_immaculate_conception = True def get_dia_do_comercio(self, year): """ Return Dia do Comércio variable date It happens on the 3rd Monday of october. """ return BrazilRioDeJaneiro.get_nth_weekday_in_month(year, 10, MON, 3) def get_variable_days(self, year): days = super().get_variable_days(year) days.append((self.get_dia_do_comercio(year), "Dia do Comércio")) return days @iso_register('BR-RN') class BrazilRioGrandeDoNorte(Brazil): "Brazil Rio Grande do Norte State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (10, 3, "Mártires de Cunhaú e Uruaçuu"), ) include_sao_pedro = True sao_pedro_label = "Dua de São Pedro" @iso_register('BR-RS') class BrazilRioGrandeDoSul(Brazil): "Brazil Rio Grande do Sul State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (9, 20, "Revolução Farroupilha"), ) @iso_register('BR-RO') class BrazilRondonia(Brazil): "Brazil Rondônia State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (1, 4, "Criação do estado"), (6, 18, "Dia do Evangélico"), ) @iso_register('BR-RR') class BrazilRoraima(Brazil): "Brazil Roraima State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (10, 5, "Criação de Roraima"), ) @iso_register('BR-SC') class BrazilSantaCatarina(Brazil): "Brazil Santa Catarina State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (8, 11, "Criação da capitania, separando-se de SP"), (11, 25, "Dia de Santa Catarina de Alexandria"), ) @iso_register('BR-SP') class BrazilSaoPauloState(Brazil): "Brazil São Paulo State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (7, 9, "Constitutional Revolution of 1932"), ) class BrazilSaoPauloCity(BrazilSaoPauloState): "Brazil São Paulo City" FIXED_HOLIDAYS = BrazilSaoPauloState.FIXED_HOLIDAYS + ( (1, 25, "Anniversary of the city of São Paulo"), ) include_fat_tuesday = True fat_tuesday_label = "Carnaval" include_easter_sunday = True include_corpus_christi = True include_good_friday = True good_friday_label = "Sexta-feira da Paixão" include_consciencia_negra = True consciencia_negra_label = "Dia da Consciência Negra" @iso_register('BR-SE') class BrazilSergipe(Brazil): "Brazil Sergipe State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (7, 8, "Autonomia política de Sergipe"), ) @iso_register('BR-TO') class BrazilTocantins(Brazil): "Brazil Tocantins State" FIXED_HOLIDAYS = Brazil.FIXED_HOLIDAYS + ( (1, 1, "Instalação de Tocantins"), (9, 8, "Nossa Senhora da Natividade"), (10, 5, "Criação de Tocantins"), (3, 18, "Autonomia do estado de Tocantins"), ) class BrazilVitoriaCity(BrazilEspiritoSanto): "Brazil Vitória City" FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + ( (4, 24, "Nossa Senhora da Penha"), # Our Lady of Pain? (9, 8, "Nossa Senhora da Vitória"), # Our Lady of Vitória (9, 8, "Aniversário de Vitória"), ) include_corpus_christi = True include_good_friday = True good_friday_label = "Paixão do Cristo" class BrazilVilaVelhaCity(BrazilEspiritoSanto): "Brazil Vila Velha City" FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + ( (5, 23, "Colonização do Solo Espírito-santense"), ) class BrazilCariacicaCity(BrazilEspiritoSanto): "Brazil Cariacica City" FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + ( (4, 13, "Nossa Senhora da Penha"), ) include_corpus_christi = True include_good_friday = True good_friday_label = "Paixão do Cristo" include_sao_joao = True sao_joao_label = "São João Batista / Aniversãrio de Cariacica" class BrazilGuarapariCity(BrazilEspiritoSanto): "Brazil Guarapari City" FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + ( (9, 19, "Emancipação de Guarapari"), ) include_sao_pedro = True include_consciencia_negra = True consciencia_negra_day = (11, 29) include_immaculate_conception = True class BrazilSerraCity(BrazilEspiritoSanto): "Brazil Serra City" FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + ( (12, 26, "Dia do Serrano"), ) include_fat_tuesday = True fat_tuesday_label = "Carnaval" include_ash_wednesday = True ash_wednesday_label = "Quarta-feira de cinzas" include_good_friday = True good_friday_label = "Paixão do Cristo" include_sao_pedro = True include_immaculate_conception = True def get_variable_days(self, year): days = super().get_variable_days(year) carnaval_tuesday = self.get_fat_tuesday(year) days.append((carnaval_tuesday - timedelta(days=1), "Carnaval Monday")) return days class BrazilRioBrancoCity(BrazilAcre): "Brazil Rio Branco City" FIXED_HOLIDAYS = BrazilAcre.FIXED_HOLIDAYS + ( (12, 28, "Aniversário de Rio Branco"), ) class BrazilMaceioCity(BrazilAlagoas): "Brazil Maceió City" FIXED_HOLIDAYS = BrazilAlagoas.FIXED_HOLIDAYS + ( (12, 5, "Aniversário de Maceió"), ) class BrazilManausCity(BrazilAmazonas): "Brazil Manaus City" FIXED_HOLIDAYS = BrazilAmazonas.FIXED_HOLIDAYS + ( (10, 24, "Aniversário de Manaus"), ) class BrazilMacapaCity(BrazilAmapa): "Brazil Macapá City" FIXED_HOLIDAYS = BrazilAmapa.FIXED_HOLIDAYS + ( (2, 4, "Aniversário de Macapá"), ) class BrazilSalvadorCity(BrazilBahia): "Brazil Salvador City" FIXED_HOLIDAYS = BrazilBahia.FIXED_HOLIDAYS + ( (3, 29, "Aniversário de Salvador"), ) class BrazilFortalezaCity(BrazilCeara): "Brazil Fortaleza City" FIXED_HOLIDAYS = BrazilCeara.FIXED_HOLIDAYS + ( (4, 13, "Aniversário de Fortaleza"), ) class BrazilGoianiaCity(BrazilGoias): "Brazil Goiânia City" FIXED_HOLIDAYS = BrazilGoias.FIXED_HOLIDAYS + ( (10, 24, "Aniversário de Goiânia"), ) class BrazilBeloHorizonteCity(BrazilMinasGerais): "Brazil Belo Horizonte City" FIXED_HOLIDAYS = BrazilMinasGerais.FIXED_HOLIDAYS + ( (12, 12, "Aniversário de Belo Horizonte"), ) class BrazilCampoGrandeCity(BrazilMatoGrossoDoSul): "Brazil Campo Grande City" FIXED_HOLIDAYS = BrazilMatoGrossoDoSul.FIXED_HOLIDAYS + ( (8, 26, "Aniversário de Campo Grande"), ) class BrazilCuiabaCity(BrazilMatoGrosso): "Brazil Cuiabá City" FIXED_HOLIDAYS = BrazilMatoGrosso.FIXED_HOLIDAYS + ( (4, 8, "Aniversário de Cuiabá"), ) include_easter_sunday = True include_corpus_christi = True include_good_friday = True good_friday_label = "Sexta-feira da Paixão" class BrazilBelemCity(BrazilPara): "Brazil Belém City" FIXED_HOLIDAYS = BrazilPara.FIXED_HOLIDAYS + ( (1, 12, "Aniversário de Belém"), ) class BrazilJoaoPessoaCity(BrazilParaiba): "Brazil João Pessoa City" FIXED_HOLIDAYS = BrazilParaiba.FIXED_HOLIDAYS + ( (8, 5, "Aniversário de João Pessoa"), ) class BrazilRecifeCity(BrazilPernambuco): "Brazil Recife City" FIXED_HOLIDAYS = BrazilPernambuco.FIXED_HOLIDAYS + ( (3, 12, "Aniversário de Recife"), ) class BrazilTeresinaCity(BrazilPiaui): "Brazil Teresina City" FIXED_HOLIDAYS = BrazilPiaui.FIXED_HOLIDAYS + ( (8, 16, "Aniversário de Teresina"), ) class BrazilCuritibaCity(BrazilParana): "Brazil Curitiba City" FIXED_HOLIDAYS = BrazilParana.FIXED_HOLIDAYS + ( (3, 29, "Aniversário de Curitiba"), ) class BrazilNatalCity(BrazilRioGrandeDoNorte): "Brazil Natal City" FIXED_HOLIDAYS = BrazilRioGrandeDoNorte.FIXED_HOLIDAYS + ( (12, 25, "Aniversário de Natal"), ) class BrazilPortoVelhoCity(BrazilRondonia): "Brazil Porto Velho City" FIXED_HOLIDAYS = BrazilRondonia.FIXED_HOLIDAYS + ( (10, 2, "Aniversário de Porto Velho"), ) class BrazilBoaVistaCity(BrazilRoraima): "Brazil Boa Vista City" FIXED_HOLIDAYS = BrazilRoraima.FIXED_HOLIDAYS + ( (6, 9, "Aniversário de Boa Vista"), ) class BrazilPortoAlegreCity(BrazilRioGrandeDoSul): "Brazil Porto Alegre City" FIXED_HOLIDAYS = BrazilRioGrandeDoSul.FIXED_HOLIDAYS + ( (3, 26, "Aniversário de Porto Alegre"), ) class BrazilChapecoCity(BrazilSantaCatarina): "Brazil Chapecó City" FIXED_HOLIDAYS = BrazilSantaCatarina.FIXED_HOLIDAYS + ( (8, 25, "Aniversário de Chapecó"), ) class BrazilFlorianopolisCity(BrazilSantaCatarina): "Brazil Florianópolis City" FIXED_HOLIDAYS = BrazilSantaCatarina.FIXED_HOLIDAYS + ( (3, 23, "Aniversário de Florianópolis"), ) class BrazilJoinvilleCity(BrazilSantaCatarina): "Brazil Joinville City" FIXED_HOLIDAYS = BrazilSantaCatarina.FIXED_HOLIDAYS + ( (3, 9, "Aniversário de Joinville"), ) class BrazilAracajuCity(BrazilSergipe): "Brazil Aracaju City" FIXED_HOLIDAYS = BrazilSergipe.FIXED_HOLIDAYS + ( (3, 17, "Aniversário de Aracaju"), ) class BrazilSorocabaCity(BrazilSaoPauloState): "Brazil Sorocaba City" FIXED_HOLIDAYS = BrazilSaoPauloState.FIXED_HOLIDAYS + ( (8, 15, "Aniversário de Sorocaba"), ) class BrazilPalmasCity(BrazilTocantins): "Brazil Palmas City" FIXED_HOLIDAYS = BrazilTocantins.FIXED_HOLIDAYS + ( (5, 20, "Aniversário de Palmas"), ) class BrazilBankCalendar(Brazil): """ Calendar that considers only working days for bank transactions for companies and the general public """ include_fat_tuesday = True fat_tuesday_label = "Tuesday carnaval" include_good_friday = True include_ash_wednesday = True include_corpus_christi = True include_easter_sunday = False def get_last_day_of_year_for_only_internal_bank_trans(self, year): """ The last day of year isn't a working day for public bank transactions in Brazil. More details can be read in http://www.bcb.gov.br/pre/bc_atende/port/servicos4.asp """ last_day = date(year, 12, 31) if last_day.weekday() == SAT: return last_day - timedelta(days=1) elif last_day.weekday() == SUN: return last_day - timedelta(days=2) return last_day def get_variable_days(self, year): """ Define the brazilian variable holidays and the last day for only internal bank transactions """ days = super().get_variable_days(year) tuesday_carnaval = self.get_fat_tuesday(year) monday_carnaval = tuesday_carnaval - timedelta(days=1) days.append((monday_carnaval, "Monday carnaval")) days.append(( self.get_last_day_of_year_for_only_internal_bank_trans(year), "Last day of year for only internal bank transactions" )) return days def find_following_working_day(self, day): """ Find for the next working day by ignoring weekends, fixed and non fixed holidays and the last working day for only internal bank transactions in Brazil """ while not self.is_working_day(day): day = day + timedelta(days=1) return day IBGE_TUPLE = ( ('BR-IBGE-12', BrazilAcre), ('BR-IBGE-27', BrazilAlagoas), ('BR-IBGE-16', BrazilAmapa), ('BR-IBGE-13', BrazilAmazonas), ('BR-IBGE-29', BrazilBahia), ('BR-IBGE-23', BrazilCeara), ('BR-IBGE-53', BrazilDistritoFederal), ('BR-IBGE-32', BrazilEspiritoSanto), ('BR-IBGE-52', BrazilGoias), ('BR-IBGE-21', BrazilMaranhao), ('BR-IBGE-31', BrazilMinasGerais), ('BR-IBGE-51', BrazilMatoGrosso), ('BR-IBGE-50', BrazilMatoGrossoDoSul), ('BR-IBGE-15', BrazilPara), ('BR-IBGE-25', BrazilParaiba), ('BR-IBGE-26', BrazilPernambuco), ('BR-IBGE-22', BrazilPiaui), ('BR-IBGE-41', BrazilParana), ('BR-IBGE-33', BrazilRioDeJaneiro), ('BR-IBGE-24', BrazilRioGrandeDoNorte), ('BR-IBGE-43', BrazilRioGrandeDoSul), ('BR-IBGE-11', BrazilRondonia), ('BR-IBGE-14', BrazilRoraima), ('BR-IBGE-42', BrazilSantaCatarina), ('BR-IBGE-35', BrazilSaoPauloState), ('BR-IBGE-3550308', BrazilSaoPauloCity), ('BR-IBGE-28', BrazilSergipe), ('BR-IBGE-17', BrazilTocantins), ('BR-IBGE-3205309', BrazilVitoriaCity), ('BR-IBGE-3205200', BrazilVilaVelhaCity), ('BR-IBGE-3201308', BrazilCariacicaCity), ('BR-IBGE-3202405', BrazilGuarapariCity), ('BR-IBGE-3205002', BrazilSerraCity), ('BR-IBGE-1200401', BrazilRioBrancoCity), ('BR-IBGE-2704302', BrazilMaceioCity), ('BR-IBGE-1302603', BrazilManausCity), ('BR-IBGE-1600303', BrazilMacapaCity), ('BR-IBGE-2927408', BrazilSalvadorCity), ('BR-IBGE-2304400', BrazilFortalezaCity), ('BR-IBGE-5208707', BrazilGoianiaCity), ('BR-IBGE-3106200', BrazilBeloHorizonteCity), ('BR-IBGE-5002704', BrazilCampoGrandeCity), ('BR-IBGE-5103403', BrazilCuiabaCity), ('BR-IBGE-1501402', BrazilBelemCity), ('BR-IBGE-2507507', BrazilJoaoPessoaCity), ('BR-IBGE-2611606', BrazilRecifeCity), ('BR-IBGE-2211001', BrazilTeresinaCity), ('BR-IBGE-4106902', BrazilCuritibaCity), ('BR-IBGE-2408102', BrazilNatalCity), ('BR-IBGE-1100205', BrazilPortoVelhoCity), ('BR-IBGE-1400100', BrazilBoaVistaCity), ('BR-IBGE-4314902', BrazilPortoAlegreCity), ('BR-IBGE-4204202', BrazilChapecoCity), ('BR-IBGE-4205407', BrazilFlorianopolisCity), ('BR-IBGE-4209102', BrazilJoinvilleCity), ('BR-IBGE-2800308', BrazilAracajuCity), ('BR-IBGE-3552205', BrazilSorocabaCity), ('BR-IBGE-1721000', BrazilPalmasCity), ) IBGE_REGISTER = dict(IBGE_TUPLE) calendra-7.9.0/calendra/america/canada.py000066400000000000000000000237041457013633400202470ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, SUN, MON, SAT from ..registry_tools import iso_register @iso_register('CA') class Canada(WesternCalendar): "Canada" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (7, 1, "Canada Day"), ) shift_new_years_day = True def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) days.append( (Canada.get_nth_weekday_in_month(year, 9, MON, 1), "Labor Day") ) # Canada day canadaday = date(year, 7, 1) if canadaday.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(canadaday) days.append((shift, "Canada Day Shift")) christmas = date(year, 12, 25) if christmas.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(christmas) days.append((shift, "Christmas Shift")) return days class LateFamilyDayMixin: "3rd Monday of February" def get_family_day(self, year, label="Family Day"): return self.get_nth_weekday_in_month(year, 2, MON, 3), label class VictoriaDayMixin: "Monday preceding the 25th of May" def get_victoria_day(self, year): for day in range(18, 25): if date(year, 5, day).weekday() == MON: return date(year, 5, day), "Victoria Day" class AugustCivicHolidayMixin: "1st Monday of August; different names depending on location" def get_civic_holiday(self, year, label="Civic Holiday"): return self.get_nth_weekday_in_month(year, 8, MON), label class ThanksgivingMixin: "2nd Monday of October" def get_thanksgiving(self, year): thanksgiving = self.get_nth_weekday_in_month(year, 10, MON, 2) return thanksgiving, "Thanksgiving" class BoxingDayMixin: "26th of December; shift to next working day" def get_boxing_day(self, year): boxingday = date(year, 12, 26) if boxingday.weekday() == MON: days = [(boxingday, "Boxing Day"), (date(year, 12, 27), "Boxing Day (Shift)")] elif boxingday.weekday() == SAT or boxingday.weekday() == SUN: days = [(boxingday, "Boxing Day"), (date(year, 12, 28), "Boxing Day (Shift)")] else: days = [(boxingday, "Boxing Day")] return days class StJeanBaptisteMixin: "24th of June; shift to next working day" def get_st_jean(self, year): stjean = date(year, 6, 24) if stjean.weekday() in self.get_weekend_days(): days = [(stjean, "St Jean Baptiste"), (self.find_following_working_day(stjean), "St Jean Baptiste (Shift)")] else: days = [(stjean, "St Jean Baptiste")] return days class RemembranceDayShiftMixin: "11th of November; shift to next day" def get_remembrance_day(self, year): remembranceday = date(year, 11, 11) if remembranceday.weekday() in self.get_weekend_days(): days = [(remembranceday, "Remembrance Day"), (self.find_following_working_day(remembranceday), "Remembrance Day (Shift)")] else: days = [(remembranceday, "Remembrance Day")] return days @iso_register('CA-ON') class Ontario(BoxingDayMixin, ThanksgivingMixin, VictoriaDayMixin, LateFamilyDayMixin, AugustCivicHolidayMixin, Canada): "Ontario" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_family_day(year)), (self.get_victoria_day(year)), (self.get_civic_holiday(year, "Civic Holiday (Not for all)")), (self.get_thanksgiving(year)), ]) days.extend(self.get_boxing_day(year)) return days @iso_register('CA-QC') class Quebec(VictoriaDayMixin, StJeanBaptisteMixin, ThanksgivingMixin, Canada): "Quebec" include_easter_monday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_victoria_day(year)), (self.get_thanksgiving(year)), ]) days.extend(self.get_st_jean(year)) return days @iso_register('CA-BC') class BritishColumbia(VictoriaDayMixin, AugustCivicHolidayMixin, ThanksgivingMixin, Canada): "British Columbia" include_good_friday = True FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + ( (11, 11, "Remembrance Day"), ) def get_family_day(self, year): """ Return Family Day for British Columbia. From 2013 to 2018, Family Day was on 2nd MON of February As of 2019, Family Day happens on 3rd MON of February """ label = "Family Day" if year >= 2019: return self.get_nth_weekday_in_month(year, 2, MON, 3), label return self.get_nth_weekday_in_month(year, 2, MON, 2), label def get_variable_days(self, year): days = super().get_variable_days(year) if year >= 2013: days.append(self.get_family_day(year)) days.extend([ (self.get_victoria_day(year)), (self.get_civic_holiday(year, "British Columbia Day")), (self.get_thanksgiving(year)), ]) return days @iso_register('CA-AB') class Alberta(LateFamilyDayMixin, VictoriaDayMixin, ThanksgivingMixin, Canada): "Alberta" include_good_friday = True FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + ( (11, 11, "Remembrance Day"), ) def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_family_day(year)), (self.get_victoria_day(year)), (self.get_thanksgiving(year)), ]) return days @iso_register('CA-SK') class Saskatchewan(LateFamilyDayMixin, VictoriaDayMixin, RemembranceDayShiftMixin, AugustCivicHolidayMixin, ThanksgivingMixin, Canada): "Saskatchewan" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_family_day(year)), (self.get_victoria_day(year)), (self.get_civic_holiday(year)), (self.get_thanksgiving(year)), ]) days.extend(self.get_remembrance_day(year)) return days @iso_register('CA-MB') class Manitoba(LateFamilyDayMixin, VictoriaDayMixin, AugustCivicHolidayMixin, ThanksgivingMixin, Canada): "Manitoba" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_family_day(year, "Louis Riel Day")), (self.get_victoria_day(year)), (self.get_civic_holiday(year)), (self.get_thanksgiving(year)), ]) return days @iso_register('CA-NB') class NewBrunswick(AugustCivicHolidayMixin, Canada): "New Brunswick" FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + ( (11, 11, "Remembrance Day"), ) include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_civic_holiday(year)) return days @iso_register('CA-NS') class NovaScotia(RemembranceDayShiftMixin, LateFamilyDayMixin, Canada): "Nova Scotia" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_remembrance_day(year)) if year >= 2015: days.append(self.get_family_day(year, "Viola Desmond Day")) return days @iso_register('CA-PE') class PrinceEdwardIsland(LateFamilyDayMixin, RemembranceDayShiftMixin, Canada): "Prince Edward Island" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_family_day(year, "Islander Day")) days.extend(self.get_remembrance_day(year)) return days @iso_register('CA-NL') class Newfoundland(Canada): "Newfoundland and Labrador" include_good_friday = True @iso_register('CA-YT') class Yukon(VictoriaDayMixin, ThanksgivingMixin, Canada): "Yukon" FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + ( (11, 11, "Remembrance Day"), ) include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_nth_weekday_in_month(year, 8, MON, 3), "Discovery Day"), (self.get_victoria_day(year)), (self.get_thanksgiving(year)), ]) return days @iso_register('CA-NT') class NorthwestTerritories(RemembranceDayShiftMixin, VictoriaDayMixin, ThanksgivingMixin, Canada): "Northwest Territories" FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + ( (6, 21, "National Aboriginal Day"), ) include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_victoria_day(year)), (self.get_thanksgiving(year)), ]) days.extend(self.get_remembrance_day(year)) return days @iso_register('CA-NU') class Nunavut(VictoriaDayMixin, ThanksgivingMixin, RemembranceDayShiftMixin, Canada): "Nunavut" include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_victoria_day(year)), (self.get_thanksgiving(year)), ]) days.extend(self.get_remembrance_day(year)) nuvanutday = date(year, 7, 9) days.append((nuvanutday, "Nuvanut Day")) if nuvanutday.weekday() == SUN: days.append((date(year, 7, 10), "Nuvanut Day (Shift)")) return days calendra-7.9.0/calendra/america/chile.py000066400000000000000000000072461457013633400201270ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, MON, TUE, WED, THU, FRI, SAT from ..astronomy import solar_term from ..registry_tools import iso_register # https://www.feriados.cl # http://www.feriadoschilenos.cl @iso_register('CL') class Chile(WesternCalendar): "Chile" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 21, "Navy Day"), (9, 18, "National holiday"), (9, 19, "Army holiday"), (12, 31, "Banking Holiday"), ) # Civil holidays # Labor day (Law 2.200 and Law 18.018) include_labour_day = True # Christian holidays # Holy Week (Law 2.977) include_good_friday = True include_easter_saturday = True # Assumption (Law 2.977) include_assumption = True # All Saints (Law 2.977) include_all_saints = True # Immaculate Conception (Law 2.977) include_immaculate_conception = True def get_variable_days(self, year): # noqa: C901 days = super().get_variable_days(year) # Indigenous Peoples (Law 21.357) indigenous_peoples_day = date(year, 6, 21) if year == 2021: days.append((indigenous_peoples_day, 'Indigenous Peoples Day')) elif year > 2021: june_solstice = solar_term(year, 90, 'America/Santiago') days.append((june_solstice, 'Indigenous Peoples Day')) # Saint Peter and Saint Paul (Law 18.432) peter_paul = date(year, 6, 29) if year < 2000: days.append((peter_paul, 'Saint Peter and Saint Paul')) else: # floating monday (Law 19.668) if peter_paul.weekday() in [TUE, WED, THU]: days.append((Chile.get_nth_weekday_in_month(year, 6, MON, 4), 'Saint Peter and Saint Paul')) elif peter_paul.weekday() == FRI: days.append((date(year, 7, 2), 'Saint Peter and Saint Paul')) else: days.append((peter_paul, 'Columbus Day')) # Our Lady of Mount Carmel (Law 20.148) if year >= 2007: days.append((date(year, 7, 16), "Our Lady of Mount Carmel")) # National Bridge Days (Law 20.215) if year >= 2007: september_17 = date(year, 9, 17) if september_17.weekday() == MON: days.append((september_17, '"Bridge" holiday')) september_20 = date(year, 9, 20) if september_20.weekday() == FRI: days.append((september_20, '"Bridge" holiday')) # Additional Friday (Law 20.983) if year >= 2017: september_18 = date(year, 9, 18) if (september_18.weekday() == SAT): days.append((september_17, '"Bridge" holiday')) # Meeting of the two Worlds (Law 3.810) columbus_day = date(year, 10, 12) if year < 2000: days.append((columbus_day, 'Columbus Day')) else: # floating monday (Law 19.668) if columbus_day.weekday() in [TUE, WED, THU]: days.append((Chile.get_nth_weekday_in_month(year, 10, MON, 2), 'Columbus Day')) elif columbus_day.weekday() == FRI: days.append((date(year, 10, 15), 'Columbus Day')) else: days.append((columbus_day, 'Columbus Day')) # Reformation Day (Law 20.299) if year >= 2008: reformation_day = date(year, 10, 31) if reformation_day.weekday() == WED: reformation_day = date(year, 11, 2) elif reformation_day.weekday() == TUE: reformation_day = date(year, 10, 27) days.append((reformation_day, "Reformation Day")) return days calendra-7.9.0/calendra/america/colombia.py000066400000000000000000000101111457013633400206110ustar00rootroot00000000000000from datetime import timedelta, date from ..core import WesternCalendar, MON from ..registry_tools import iso_register @iso_register('CO') class Colombia(WesternCalendar): "Colombia" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (7, 20, "Independence Day"), (8, 7, "Boyacá Battle"), ) # Civil holidays include_labour_day = True # Christian holidays include_palm_sunday = True include_holy_thursday = True include_good_friday = True include_easter_sunday = True include_corpus_christi = True include_immaculate_conception = True def get_epiphany(self, year): """ Epiphany is shifted in Colombia """ base_day = date(year, 1, 6) return self.get_first_weekday_after(base_day, MON) def get_saint_joseph(self, year): base_day = date(year, 3, 19) return self.get_first_weekday_after(base_day, MON) def get_ascension(self, year): # By default, Ascension falls on THU. # But in Colombia, they celebrate it the next MON. base_day = self.get_ascension_thursday(year) return self.get_first_weekday_after(base_day, MON) def get_corpus_christi(self, year): # By default, Corpus Christi falls 60 days after Easter. # But in Colombia, they celebrate it the next MON. base_day = super().get_corpus_christi(year) return self.get_first_weekday_after(base_day, MON) def get_sacred_heart(self, year): # By default, Sacred Heart falls 68 days after Easter. # But in Colombia, they celebrate it the next MON. base_day = self.get_easter_sunday(year) + timedelta(days=68) return self.get_first_weekday_after(base_day, MON) def get_saint_peter_and_saint_paul(self, year): base_day = date(year, 6, 29) return self.get_first_weekday_after(base_day, MON) def get_assumption(self, year): # By default, Assumption is a fixed date (August 15th) # But in Colombia, they celebrate it the next MON. base_day = date(year, 8, 15) return self.get_first_weekday_after(base_day, MON) def get_day_of_the_races(self, year): """ Return Day of the Races and Hispanity a.k.a. "Día de la Raza" Fixed to the next MON after October 12th (Columbus Day) """ base_day = date(year, 10, 12) return self.get_first_weekday_after(base_day, MON) def get_all_saints(self, year): # By default, All Saints is a fixed date (November 1st) # But in Colombia, they celebrate it the next MON. base_day = date(year, 11, 1) return self.get_first_weekday_after(base_day, MON) def get_cartagena_independence(self, year): """ Cartagena independance day Fixed to the next MON after November 11th. """ base_day = date(year, 11, 11) return self.get_first_weekday_after(base_day, MON) def get_variable_days(self, year): """ Return variable holidays for Colombia The following days are set to "the next MON after the 'true' date". * Epiphany, * Saint Joseph, * Ascension, * Corpus Christi, * Sacred Heart, * Saint Peter & Saint Paul * Assumption * Columbus Day / Race Day * All Saints * Cartagena Independance """ days = super().get_variable_days(year) days.extend([ (self.get_epiphany(year), "Epiphany"), (self.get_saint_joseph(year), "Saint Joseph"), (self.get_ascension(year), "Ascension"), (self.get_sacred_heart(year), "Sacred Heart"), (self.get_saint_peter_and_saint_paul(year), "Saint Peter and Saint Paul"), (self.get_assumption(year), "Assumption of Mary to Heaven"), (self.get_day_of_the_races(year), "Day of the Races and Hispanity"), (self.get_all_saints(year), "All Saints"), (self.get_cartagena_independence(year), "Cartagena's Independence"), ]) return days calendra-7.9.0/calendra/america/el_salvador.py000066400000000000000000000011001457013633400213150ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('SV') class ElSalvador(WesternCalendar): "El Salvador" # Civil holidays include_labour_day = True # Christian holidays include_holy_thursday = True include_good_friday = True include_easter_saturday = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 10, "Mothers' Day"), (6, 17, "Fathers' Day"), (8, 6, "Celebrations of San Salvador"), (9, 15, "Independence Day"), (11, 2, "All Saints Day"), ) calendra-7.9.0/calendra/america/mexico.py000066400000000000000000000034261457013633400203230ustar00rootroot00000000000000from datetime import date, timedelta from dateutil import relativedelta as rd from ..core import WesternCalendar, ChristianMixin from ..core import SUN, SAT from ..core import Holiday from ..registry_tools import iso_register @iso_register('MX') class Mexico(WesternCalendar, ChristianMixin): "Mexico" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 1, "Labour Day"), (9, 16, "Independence Day"), ) shift_new_years_day = True @property def observance_shift(self): return Holiday.nearest_weekday def get_variable_days(self, year): days = super().get_variable_days(year) days.append(Holiday( date(year, 2, 1) + rd.relativedelta(weekday=rd.MO(1)), "Constitution Day", )) days.append(Holiday( date(year, 3, 1) + rd.relativedelta(weekday=rd.MO(3)), "Benito Juárez's birthday", )) days.append(Holiday( date(year, 11, 1) + rd.relativedelta(weekday=rd.MO(3)), "Revolution Day", )) return days def get_calendar_holidays(self, year): days = super().get_calendar_holidays(year) # If any statutory day is on Sunday, the monday is off # If it's on a Saturday, the Friday is off for day, label in days: if day.weekday() == SAT: days.append((day - timedelta(days=1), f"{label} substitute")) elif day.weekday() == SUN: days.append((day + timedelta(days=1), f"{label} substitute")) # Extra: if new year's day is a saturday, the friday before is off next_new_year = date(year + 1, 1, 1) if next_new_year.weekday(): days.append((date(year, 12, 31), "New Year Day substitute")) return days calendra-7.9.0/calendra/america/panama.py000066400000000000000000000015251457013633400202720ustar00rootroot00000000000000from datetime import timedelta from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('PA') class Panama(WesternCalendar): "Panama" # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_easter_saturday = True include_easter_sunday = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 9, "Martyrs' Day"), (11, 3, "Independence Day"), (11, 5, "Colon Day"), (11, 10, "Shout in Villa de los Santos"), (11, 28, "Independence from Spain"), (12, 8, "Mothers' Day"), ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_ash_wednesday(year) - timedelta(days=1), "Carnival") ) return days calendra-7.9.0/calendra/america/paraguay.py000066400000000000000000000042221457013633400206430ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('PY') class Paraguay(WesternCalendar): "Paraguay" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 14, "Independence Day"), (6, 12, "Chaco Armistice"), (9, 19, "Army holiday"), ) # Civil holidays include_labour_day = True # Christian holidays include_holy_thursday = True include_good_friday = True include_easter_saturday = True include_immaculate_conception = True immaculate_conception_label = "Virgin of Caacupé Day" def get_heroes_day(self, year): """ Heroes Day is a fixed holidays. In 2017, it has been moved to February 27th ; otherwise, it happens on March 1st. ref: https://en.wikipedia.org/wiki/Public_holidays_in_Paraguay """ label = "Heroes' Day" if year == 2017: day = date(year, 2, 27) else: day = date(year, 3, 1) return day, label def get_founding_of_asuncion(self, year): """ Return the Founding of Asunción. In 2017, it has been moved to August 14th ; otherwise it happens on August 15th. """ label = "Founding of Asunción" if year == 2017: day = date(year, 8, 14) else: day = date(year, 8, 15) return day, label def get_boqueron_battle_victory_day(self, year): """ Return Boqueron Battle Victory Day. In 2017, it has been moved to October 2nd ; otherwise it happens on September 29th. """ label = "Boqueron Battle Victory Day" if year == 2017: day = date(year, 10, 2) else: day = date(year, 9, 29) return day, label def get_fixed_holidays(self, year): """ Return fixed holidays for Paraguay. """ days = super().get_fixed_holidays(year) days.append(self.get_heroes_day(year)) days.append(self.get_founding_of_asuncion(year)) days.append(self.get_boqueron_battle_victory_day(year)) return days calendra-7.9.0/calendra/asia/000077500000000000000000000000001457013633400157745ustar00rootroot00000000000000calendra-7.9.0/calendra/asia/__init__.py000066400000000000000000000011051457013633400201020ustar00rootroot00000000000000from .china import China from .hong_kong import HongKong, HongKongBank from .japan import Japan, JapanBank from .malaysia import Malaysia from .qatar import Qatar from .singapore import Singapore from .south_korea import SouthKorea from .taiwan import Taiwan from .israel import Israel from .philippines import Philippines from .kazakhstan import Kazakhstan __all__ = ( 'China', 'HongKong', 'HongKongBank', 'Japan', 'JapanBank', 'Malaysia', 'Qatar', 'Singapore', 'SouthKorea', 'Taiwan', 'Israel', 'Philippines', 'Kazakhstan' ) calendra-7.9.0/calendra/asia/china.py000066400000000000000000000156221457013633400174360ustar00rootroot00000000000000from datetime import date import warnings from ..core import ChineseNewYearCalendar from ..registry_tools import iso_register from ..exceptions import CalendarError holidays = { 2018: { 'Ching Ming Festival': [(4, 5), (4, 6), (4, 7)], 'Labour Day Holiday': [(4, 29), (4, 30), (5, 1)], 'Dragon Boat Festival': [(6, 18)], 'Mid-Autumn Festival': [(9, 24)], 'New year': [(12, 30), (12, 31)] }, 2019: { 'Ching Ming Festival': [(4, 5)], 'Labour Day Holiday': [(5, 1), (5, 2), (5, 3)], 'Dragon Boat Festival': [(6, 7)], 'Mid-Autumn Festival': [(9, 13)] }, 2020: { 'Ching Ming Festival': [(4, 4), (4, 5), (4, 6)], 'Labour Day Holiday': [(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)], 'Dragon Boat Festival': [(6, 25), (6, 26), (6, 27)], 'National Day': [(10, 8)] }, 2021: { 'Ching Ming Festival': [(4, 3), (4, 4), (4, 5)], 'Labour Day Holiday': [(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)], 'Dragon Boat Festival': [(6, 12), (6, 13), (6, 14)], 'Mid-Autumn Festival': [(9, 19), (9, 20), (9, 21)] }, 2022: { 'Ching Ming Festival': [(4, 3), (4, 4), (4, 5)], 'Labour Day Holiday': [(4, 30), (5, 1), (5, 2), (5, 3), (5, 4)], 'Dragon Boat Festival': [(6, 3), (6, 4), (6, 5)], 'Mid-Autumn Festival': [(9, 10), (9, 11), (9, 12)] }, 2023: { 'Ching Ming Festival': [(4, 5)], 'Labour Day Holiday': [(4, 29), (4, 30), (5, 1), (5, 2), (5, 3)], 'Dragon Boat Festival': [(6, 22), (6, 23), (6, 24)], 'Mid-Autumn Festival': [(9, 29)], 'National Day': [(9, 30)] }, 2024: { 'Spring Festival': [(2, 16), (2, 17)], 'Ching Ming Festival': [(4, 4), (4, 5), (4, 6)], 'Labour Day Holiday': [(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)], 'Dragon Boat Festival': [(6, 8), (6, 9), (6, 10)], 'Mid-Autumn Festival': [(9, 15), (9, 16), (9, 17)], }, } workdays = { 2018: { 'Spring Festival Shift': [(2, 11), (2, 24)], 'Ching Ming Festival Shift': [(4, 8)], 'Labour Day Holiday Shift': [(4, 28)], 'National Day Shift': [(9, 29), (9, 30)], 'New year Shift': [(12, 29)] }, 2019: { 'Spring Festival Shift': [(2, 2), (2, 3)], 'Labour Day Holiday Shift': [(4, 28), (5, 5)], 'National Day Shift': [(9, 29), (10, 12)], }, 2020: { 'Spring Festival Shift': [(1, 19), (2, 1)], 'Labour Day Holiday Shift': [(4, 26), (5, 9)], 'Dragon Boat Festival Shift': [(6, 28)], 'National Day Shift': [(9, 27), (10, 10)] }, 2021: { 'Spring Festival Shift': [(2, 7), (2, 20)], 'Labour Day Holiday Shift': [(4, 25), (5, 8)], 'Mid-Autumn Festival Shift': [(9, 18)], 'National Day Shift': [(9, 26), (10, 9)] }, 2022: { 'Spring Festival Shift': [(1, 29), (1, 30)], 'Ching Ming Festival Shift': [(4, 2)], 'Labour Day Holiday Shift': [(4, 24), (5, 7)], 'National Day Shift': [(10, 8), (10, 9)] }, 2023: { 'Spring Festival Shift': [(1, 28), (1, 29)], 'Labour Day Holiday Shift': [(4, 23), (5, 6)], 'Dragon Boat Festival Shift': [(6, 25)], 'National Day Shift': [(10, 7), (10, 8)] }, 2024: { 'Spring Festival Shift': [(2, 4), (2, 9), (2, 18)], 'Ching Ming Festival Shift': [(4, 7)], 'Labour Day Holiday Shift': [(4, 28), (5, 11)], 'Mid-Autumn Festival Shift': [(9, 14)], 'National Day Shift': [(9, 29), (10, 12)] }, } @iso_register('CN') class China(ChineseNewYearCalendar): "China" # WARNING: Support 2018-2024 currently, need update every year. shift_new_years_day = True include_chinese_new_year_eve = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.extra_working_days = [] for year, data in workdays.items(): for working_day_name, day_list in data.items(): for v in day_list: self.extra_working_days.append(date(year, v[0], v[1])) def get_calendar_holidays(self, year): year_min, year_max = min(holidays), max(holidays) warnings.warn( f"Support years {year_min}-{year_max} currently, " f"need update every year." ) if year not in holidays: msg = f"Need configure {year} for China." raise CalendarError(msg) return super().get_calendar_holidays(year) def get_variable_days(self, year): days = [(day, holiday_name) for (day, holiday_name) in super().get_variable_days(year) if day not in self.extra_working_days] # Spring Festival, eve, 1.1, and 1.2 - 1.6 in lunar day for i in range(2, 7): day = ChineseNewYearCalendar.lunar(year, 1, i) if day not in self.extra_working_days: days.append((day, "Spring Festival")) # National Days, 10.1 - 10.7 in general for i in range(1, 8): day = date(year, 10, i) if day not in self.extra_working_days: days.append((day, "National Day")) # other holidays for holiday_name, day_list in holidays[year].items(): for v in day_list: days.append((date(year, v[0], v[1]), holiday_name)) return days def is_working_day(self, day, extra_working_days=None, extra_holidays=None): extra_working_days = extra_working_days or self.extra_working_days return super().is_working_day(day, extra_working_days, extra_holidays) def add_working_days(self, day, delta, extra_working_days=None, extra_holidays=None, keep_datetime=False): extra_working_days = extra_working_days or self.extra_working_days return super().add_working_days(day, delta, extra_working_days, extra_holidays, keep_datetime) def sub_working_days(self, day, delta, extra_working_days=None, extra_holidays=None, keep_datetime=False): extra_working_days = extra_working_days or self.extra_working_days return super().sub_working_days(day, delta, extra_working_days, extra_holidays, keep_datetime) calendra-7.9.0/calendra/asia/hong_kong.py000066400000000000000000000063161457013633400203250ustar00rootroot00000000000000from datetime import date, timedelta from ..core import ( ChineseNewYearCalendar, WesternMixin, SUN, SAT ) from ..astronomy import solar_term from ..registry_tools import iso_register @iso_register('HK') class HongKong(WesternMixin, ChineseNewYearCalendar): "Hong Kong" # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_easter_saturday = True include_easter_monday = True include_boxing_day = True WEEKEND_DAYS = (SUN,) FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (7, 1, "SAR Establishment Day"), (10, 1, "National Day"), ) chinese_new_year_label = "Chinese Lunar New Year's Day" include_chinese_second_day = True chinese_second_day_label = "Second day of Chinese Lunar New Year" include_chinese_third_day = True chinese_third_day_label = "Third day of Chinese Lunar New Year" shift_sunday_holidays = True # Except CNY which rolls to Saturday shift_start_cny_sunday = False # Prior to 2011 this was True shift_new_years_day = True def get_variable_days(self, year): """ Hong Kong variable days """ # Prior to the "General Holidays and Employment Legislation # (Substitution of Holidays)(Amendment) Ordinance 2011", the first day # of CNY rolled to a Sat if it was on a Sun. After the Amendment, it # rolls to the following Wed if year < 2011: self.shift_start_cny_sunday = True days = super().get_variable_days(year) chingming = solar_term(year, 15, 'Asia/Hong_Kong') solar_term_chingming = chingming dupe_holiday = [chingming for day in days if chingming == day[0]] if dupe_holiday: # Roll Chingming forward a day as it clashes with another holiday chingming = chingming + timedelta(days=1) mid_autumn_label = "Day After Mid-Autumn Festival" days.extend([ (ChineseNewYearCalendar.lunar(year, 4, 8), "Buddha's Birthday"), (chingming, "Ching Ming Festival"), (ChineseNewYearCalendar.lunar(year, 5, 5), "Tuen Ng Festival"), (ChineseNewYearCalendar.lunar(year, 8, 16), mid_autumn_label), (ChineseNewYearCalendar.lunar(year, 9, 9), "Chung Yeung Festival"), ]) # All holidays that fall on SUN are shifted in # ``ChineseNewYearCalendar.get_calendar_holidays()`` # Special case for Boxing Day. # If Christmas day is on SUN, the December 27th is also a holiday if date(year, 12, 25).weekday() == SUN: days.append( (date(year, 12, 27), "The second weekday after Christmas") ) # Special case when Ching Ming and Easter overlap # Ching Ming is shifted to easter monday (but it's handled elsewhere) # Easter Monday is also shifted easter_sunday = self.get_easter_sunday(year) if easter_sunday == solar_term_chingming: days.append(( easter_sunday + timedelta(days=2), "The day following Easter Monday" )) return days class HongKongBank(HongKong): "Hong Kong Bank" WEEKEND_DAYS = (SAT, SUN) calendra-7.9.0/calendra/asia/israel.py000066400000000000000000000051311457013633400176250ustar00rootroot00000000000000from pyluach.dates import GregorianDate, HebrewDate from ..core import Calendar, FRI, SAT from ..registry_tools import iso_register @iso_register("IL") class Israel(Calendar): "Israel" include_new_years_day = False WEEKEND_DAYS = (SAT, FRI) def get_variable_days(self, year): days = super().get_variable_days(year) hebrew_date = GregorianDate(year=year, month=1, day=1).to_heb() jewish_year = hebrew_date.year holidays_hebrew_dates = [ (HebrewDate(jewish_year, 6, 29), "Rosh Hashana Eve"), (HebrewDate(jewish_year + 1, 7, 1), "Rosh Hashana"), (HebrewDate(jewish_year + 1, 7, 2), "Rosh Hashana"), (HebrewDate(jewish_year + 1, 7, 9), "Yom Kippur Eve"), (HebrewDate(jewish_year + 1, 7, 10), "Yom Kippur"), (HebrewDate(jewish_year + 1, 7, 14), "Sukkot Eve"), (HebrewDate(jewish_year + 1, 7, 15), "Sukkot"), (HebrewDate(jewish_year + 1, 7, 21), "Shmini Atzeres Eve"), (HebrewDate(jewish_year + 1, 7, 22), "Shmini Atzeres"), (HebrewDate(jewish_year, 1, 14), "Pesach Eve"), (HebrewDate(jewish_year, 1, 15), "Pesach"), (HebrewDate(jewish_year, 1, 20), "7th of Pesach Eve"), (HebrewDate(jewish_year, 1, 21), "7th of Pesach"), (HebrewDate(jewish_year, 3, 5), "Shavout Eve"), (HebrewDate(jewish_year, 3, 6), "Shavout"), ] holidays_hebrew_dates += self.get_hebrew_independence_day(jewish_year) for holiday_hebrew_date, holiday_name in holidays_hebrew_dates: days.append((holiday_hebrew_date.to_pydate(), holiday_name)) return days def get_hebrew_independence_day(self, jewish_year): """ Returns the independence day eve and independence day dates according to the given hebrew year :param jewish_year: the specific hebrew year for calculating the independence day dates :return: independence day dates in the type of List[Tuple[HebrewDate, str]] """ month = 2 day = 5 original_hebrew_independence_date = HebrewDate(jewish_year, month, day) if original_hebrew_independence_date.weekday() == 6: day = 4 if original_hebrew_independence_date.weekday() == 7: day = 3 if original_hebrew_independence_date.weekday() == 2: day = 6 return [ (HebrewDate(jewish_year, month, day - 1), "Independence Day Eve"), (HebrewDate(jewish_year, month, day), "Independence Day") ] calendra-7.9.0/calendra/asia/japan.py000066400000000000000000000104301457013633400174350ustar00rootroot00000000000000from datetime import date from ..core import Calendar, MON, SAT, SUN from ..astronomy import calculate_equinoxes from ..registry_tools import iso_register @iso_register('JP') class Japan(Calendar): "Japan" # Japan uses the "western" workweek WEEKEND_DAYS = (SAT, SUN) FIXED_HOLIDAYS = Calendar.FIXED_HOLIDAYS + ( (2, 11, "Foundation Day"), (4, 29, "Showa Day"), (5, 3, "Constitution Memorial Day"), (5, 4, "Greenery Day"), (5, 5, "Children's Day"), (11, 3, "Culture Day"), (11, 23, "Labour Thanksgiving Day"), ) def get_fixed_holidays(self, year): """ Fixed holidays for Japan. """ days = super().get_fixed_holidays(year) if year >= 2016 and year != 2021: days.append((date(year, 8, 11), "Mountain Day")) # Change in Emperor if year < 2019: days.append((date(year, 12, 23), "The Emperor's Birthday")) if year > 2019: days.append((date(year, 2, 23), "The Emperor's Birthday")) # Lots of adjustments for new emperor if year == 2019: days.extend([ (date(year, 4, 30), "Coronation Day"), (date(year, 5, 1), "Coronation Day"), (date(year, 5, 2), "Coronation Day"), (date(year, 5, 6), "Children's Day Observed"), (date(year, 8, 12), "Mountain Day Observed"), (date(year, 10, 22), "Enthronement Ceremony Day"), (date(year, 11, 4), "Culture Day Observed"), ]) if year == 2020: days.extend([ (date(year, 2, 24), "The Emperor's Birthday Observed"), (date(year, 5, 6), "Constitution Memorial Day Observed"), (date(year, 8, 10), "Mountain Day"), ]) # Mountain Day is 8/10 this year for some reason # The next year that will be different is 2024 days.remove((date(year, 8, 11), "Mountain Day")) if year == 2021: # Mountain Day is changed due to Tokyo's Olympics days.extend([ (date(year, 8, 8), "Mountain Day"), (date(year, 8, 9), "Mountain Day Observed"), ]) return days def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) equinoxes = calculate_equinoxes(year, 'Asia/Tokyo') coming_of_age_day = Japan.get_nth_weekday_in_month(year, 1, MON, 2) respect_for_the_aged = Japan.get_nth_weekday_in_month(year, 9, MON, 3) if year == 2020: # Health and Sports Day will continue on the 2nd monday # of October, except in 2020 when it will happen in July # https://www.timeanddate.com/holidays/japan/sports-day marine_day = date(2020, 7, 23) health_and_sport = date(2020, 7, 24) elif year == 2021: # Marine Day & Sport's Day are changed due to Tokyo's Olympics marine_day = date(year, 7, 22) health_and_sport = date(year, 7, 23) else: # Marine Day is on a Thursday in 2020 for some year # https://www.timeanddate.com/holidays/japan/sea-day marine_day = Japan.get_nth_weekday_in_month(year, 7, MON, 3) health_and_sport = Japan.get_nth_weekday_in_month(year, 10, MON, 2) # Health and Sports Day became "Sports Day" as of 2020 if year < 2020: health_and_sport_label = "Health and Sports Day" else: health_and_sport_label = "Sports Day" days.extend([ (coming_of_age_day, 'Coming of Age Day'), (marine_day, "Marine Day"), (equinoxes[0], "Vernal Equinox Day"), (respect_for_the_aged, "Respect-for-the-Aged Day"), (equinoxes[1], "Autumnal Equinox Day"), (health_and_sport, health_and_sport_label), ]) return days class JapanBank(Japan): """The Bank of Japan is closed additional days other than national holidays. https://www.boj.or.jp/en/about/outline/holi.htm/ """ FIXED_HOLIDAYS = Japan.FIXED_HOLIDAYS + ( (1, 2, "New Year Bank Holiday"), (1, 3, "New Year Bank Holiday"), (12, 31, "New Year Bank Holiday"), ) calendra-7.9.0/calendra/asia/kazakhstan.py000066400000000000000000000047351457013633400205160ustar00rootroot00000000000000from datetime import date from ..core import OrthodoxCalendar, IslamicCalendar from ..registry_tools import iso_register @iso_register('KZ') class Kazakhstan(OrthodoxCalendar, IslamicCalendar): 'Kazakhstan' "Sources: " "https://en.wikipedia.org/wiki/Public_holidays_in_Kazakhstan" include_christmas = False include_christmas_eve = False include_new_years_day = True include_orthodox_christmas = False include_epiphany = False include_good_friday = False include_easter_saturday = False include_easter_sunday = False include_easter_monday = False include_prophet_birthday = False include_day_after_prophet_birthday = False include_start_ramadan = False include_eid_al_fitr = False length_eid_al_fitr = 1 include_eid_al_adha = False length_eid_al_adha = 1 include_day_of_sacrifice = True day_of_sacrifice_label = "Eid al-Adha" include_islamic_new_year = False include_laylat_al_qadr = False include_nuzul_al_quran = False FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (1, 2, "Day After New Year"), (3, 8, "international Woman's Day"), (3, 21, "Nauryz Meyramy"), (3, 22, "Nauryz Meyramy"), (3, 23, "Nauryz Meyramy"), (5, 1, "Unity Day"), (5, 9, "Day Of Victory Over Fascism"), (7, 6, "Capital City Day"), (8, 30, "Constitution Day"), (12, 16, "Independence Day"), (12, 17, "Independence Day"), ) def get_fixed_holidays(self, year): # Orthodox Christmas is an official holiday in Kazakhstan since 2007 # see https://en.wikipedia.org/wiki/Public_holidays_in_Kazakhstan self.include_orthodox_christmas = (year >= 2007) days = super(OrthodoxCalendar, self).get_fixed_holidays(year) if year >= 2013: # The 'Day of the First President' and the # 'Defender of the Faterland Day' are celebrated only since 2013 # see https://en.wikipedia.org/wiki/Public_holidays_in_Kazakhstan days.append((date(year, 12, 1), "Day of the First President")) days.append((date(year, 5, 7), "Defender of the Fatherland Day")) return days def get_variable_days(self, year): # Kurban Ait (Eid al-Adha in islamic calendar) is an official holiday # in Kazakhstan since 2007 self.include_day_of_sacrifice = (year >= 2007) days = super(IslamicCalendar, self).get_variable_days(year) return days calendra-7.9.0/calendra/asia/malaysia.py000066400000000000000000000062171457013633400201540ustar00rootroot00000000000000from datetime import date from ..core import ( IslamicMixin, ChineseNewYearCalendar, SAT, SUN ) from ..registry_tools import iso_register @iso_register('MY') class Malaysia(IslamicMixin, ChineseNewYearCalendar): "Malaysia" # Civil holidays include_labour_day = True labour_day_label = "Workers' Day" # Islamic holidays include_nuzul_al_quran = True include_eid_al_fitr = True length_eid_al_fitr = 2 eid_al_fitr_label = "Hari Raya Puasa" include_day_of_sacrifice = True day_of_sacrifice_label = "Hari Raya Haji" include_islamic_new_year = True include_prophet_birthday = True # Most of th Malaysian territory uses these Week-end days WEEKEND_DAYS = (SAT, SUN) # TODO: Add calendar exceptions FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (2, 1, "Federal Territory Day"), (8, 31, "National Day"), (9, 16, "Malaysia Day"), (12, 25, "Christmas Day"), ) # Ref: https://publicholidays.com.my/deepavali/ MSIA_DEEPAVALI = { 2010: date(2010, 11, 5), 2011: date(2011, 10, 26), 2012: date(2012, 11, 13), 2013: date(2013, 11, 2), 2014: date(2014, 10, 22), 2015: date(2015, 11, 10), 2016: date(2016, 10, 29), 2017: date(2017, 10, 18), 2018: date(2018, 11, 6), 2019: date(2019, 10, 27), 2020: date(2020, 11, 14), 2021: date(2021, 11, 4), 2022: date(2022, 10, 24), 2023: date(2023, 11, 13), # in lieu of 12th Nov 2024: date(2024, 10, 31), } # Ref: https://publicholidays.com.my/thaipusam/ MSIA_THAIPUSAM = { 2010: date(2010, 1, 30), 2011: date(2011, 1, 20), 2012: date(2012, 2, 7), 2013: date(2013, 1, 28), 2014: date(2014, 1, 17), 2015: date(2015, 2, 3), 2016: date(2016, 1, 25), 2017: date(2017, 2, 9), 2018: date(2018, 1, 31), 2019: date(2019, 1, 21), 2020: date(2020, 2, 8), 2021: date(2021, 1, 28), 2022: date(2022, 1, 18), 2023: date(2023, 2, 4), 2024: date(2024, 1, 25), } chinese_new_year_label = "First Day of Lunar New Year" include_chinese_second_day = True chinese_second_day_label = "Second Day of Lunar New Year" shift_sunday_holidays = True def get_variable_days(self, year): """ Malaysia variable days """ days = super().get_variable_days(year) # Vesak Day days.append( (ChineseNewYearCalendar.lunar(year, 4, 15), "Vesak Day"), ) # Add in Deepavali and Thaipusam (hardcoded dates, so no need to shift) msia_deepavali = self.MSIA_DEEPAVALI.get(year) if not msia_deepavali: mdmsg = f'Missing date for Malaysia Deepavali for year: {year}' raise KeyError(mdmsg) days.append((msia_deepavali, 'Deepavali')) msia_thaipusam = self.MSIA_THAIPUSAM.get(year) if not msia_thaipusam: mtmsg = f'Missing date for Malaysia Thaipusam for year: {year}' raise KeyError(mtmsg) days.append((msia_thaipusam, 'Thaipusam')) return days calendra-7.9.0/calendra/asia/philippines.py000066400000000000000000000023311457013633400206710ustar00rootroot00000000000000from ..core import ( WesternMixin, IslamicMixin, ChineseNewYearCalendar, SAT, SUN ) from ..registry_tools import iso_register @iso_register('PH') class Philippines(WesternMixin, IslamicMixin, ChineseNewYearCalendar): "Philippines" # Civil holidays include_labour_day = True include_new_years_eve = True # Christian holiday include_holy_thursday = True holy_thursday_label = "Maundy Thursday" include_good_friday = True include_easter_saturday = True include_easter_sunday = True easter_saturday_label = "Black Saturday" include_all_saints = True include_all_souls = True include_immaculate_conception = True include_christmas_eve = True # Islamic holidays include_eid_al_fitr = True eid_al_fitr_label = "Eid'l Fitr" include_eid_al_adha = True day_of_sacrifice_label = "Eid'l Adha" WEEKEND_DAYS = (SAT, SUN) FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (2, 25, "EDSA Revolution Anniversary"), (4, 9, "Araw ng Kagitingan"), (6, 12, "Independence Day"), (8, 21, "Ninoy Aquino Day"), (8, 30, "National Heroes' Day"), (11, 30, "Bonifacio Day"), (12, 30, "Rizal Day"), ) calendra-7.9.0/calendra/asia/qatar.py000066400000000000000000000006051457013633400174570ustar00rootroot00000000000000from ..core import IslamicCalendar from ..registry_tools import iso_register @iso_register('QA') class Qatar(IslamicCalendar): "Qatar" include_new_years_day = False FIXED_HOLIDAYS = ( (12, 18, "National Day"), ) include_start_ramadan = True include_eid_al_fitr = True length_eid_al_fitr = 4 include_eid_al_adha = True length_eid_al_adha = 4 calendra-7.9.0/calendra/asia/singapore.py000066400000000000000000000053701457013633400203420ustar00rootroot00000000000000from datetime import date from ..core import ( WesternMixin, IslamicMixin, ChineseNewYearCalendar, SAT, SUN ) from ..registry_tools import iso_register @iso_register('SG') class Singapore(WesternMixin, IslamicMixin, ChineseNewYearCalendar): "Singapore" # Civil holidays include_labour_day = True # Christian holiday include_good_friday = True # Islamic holidays include_eid_al_fitr = True eid_al_fitr_label = "Hari Raya Puasa" include_day_of_sacrifice = True day_of_sacrifice_label = "Hari Raya Haji" FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (8, 9, "National Day"), ) # Explicitly assign these WE days, Singapore calendar is too much of a mix WEEKEND_DAYS = (SAT, SUN) # Diwali/Deepavali is sometimes celebrated on a different day to India # so this can't be put into a HinduMixin # Ref: # https://holidays.kayaposoft.com/public_holidays.php?year=2022&country=sgp DEEPAVALI = { 2000: date(2000, 10, 26), 2001: date(2001, 11, 14), 2002: date(2002, 11, 3), 2003: date(2003, 10, 23), 2004: date(2004, 11, 11), 2005: date(2005, 11, 1), 2006: date(2006, 10, 21), 2007: date(2007, 11, 8), 2008: date(2008, 10, 27), 2009: date(2009, 10, 17), 2010: date(2010, 11, 5), 2011: date(2011, 10, 26), 2012: date(2012, 11, 13), 2013: date(2013, 11, 3), 2014: date(2014, 10, 22), 2015: date(2015, 11, 10), 2016: date(2016, 10, 29), 2017: date(2017, 10, 18), 2018: date(2018, 11, 6), 2019: date(2019, 10, 27), 2020: date(2020, 11, 14), 2021: date(2021, 11, 4), 2022: date(2022, 10, 24), 2023: date(2023, 11, 13), 2024: date(2024, 10, 31), 2025: date(2025, 10, 20), 2026: date(2026, 11, 9), 2027: date(2027, 10, 28), 2028: date(2028, 11, 15), 2029: date(2029, 11, 5), 2030: date(2030, 10, 25), } chinese_new_year_label = "Chinese Lunar New Year's Day" include_chinese_second_day = True chinese_second_day_label = "Second day of Chinese Lunar New Year" shift_sunday_holidays = True def get_variable_days(self, year): """ Singapore variable days """ if year not in self.DEEPAVALI: msg = f'Missing date for Singapore Deepavali for year: {year}' raise KeyError(msg) days = super().get_variable_days(year) # Vesak Day days.append( (ChineseNewYearCalendar.lunar(year, 4, 15), "Vesak Day"), ) # Add in Deepavali (hardcoded dates, so no need to shift) days.append((self.DEEPAVALI.get(year), 'Deepavali')) return days calendra-7.9.0/calendra/asia/south_korea.py000066400000000000000000000023051457013633400206710ustar00rootroot00000000000000from ..core import ChineseNewYearCalendar from ..registry_tools import iso_register @iso_register('KR') class SouthKorea(ChineseNewYearCalendar): "South Korea" FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (3, 1, "Independence Day"), (5, 5, "Children's Day"), (6, 6, "Memorial Day"), (8, 15, "Liberation Day"), (10, 3, "National Foundation Day"), (10, 9, "Hangul Day"), (12, 25, "Christmas Day"), ) chinese_new_year_label = "Korean New Year's Day" include_chinese_new_year_eve = True chinese_new_year_eve_label = "Korean New Year's Day" include_chinese_second_day = True chinese_second_day_label = "Korean New Year's Day" def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (ChineseNewYearCalendar.lunar(year, 4, 8), "Buddha's Birthday"), # Midautumn Festival (3 days) (ChineseNewYearCalendar.lunar(year, 8, 14), "Midautumn Festival"), (ChineseNewYearCalendar.lunar(year, 8, 15), "Midautumn Festival"), (ChineseNewYearCalendar.lunar(year, 8, 16), "Midautumn Festival"), ]) return days calendra-7.9.0/calendra/asia/taiwan.py000066400000000000000000000026421457013633400176350ustar00rootroot00000000000000from datetime import date from ..core import ChineseNewYearCalendar, cleaned_date from ..astronomy import solar_term from ..registry_tools import iso_register @iso_register('TW') class Taiwan(ChineseNewYearCalendar): "Taiwan (Republic of China)" FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + ( (2, 28, "228 Peace Memorial Day"), (4, 4, "Combination of Women's Day and Children's Day"), (10, 10, "National Day/Double Tenth Day"), ) include_chinese_new_year_eve = True include_chinese_second_day = True def is_working_day(self, day, *args, **kwargs): day = cleaned_date(day) if day in (date(2021, 2, 20), date(2021, 9, 11)): return True return super().is_working_day(day, *args, **kwargs) def get_variable_days(self, year): days = super().get_variable_days(year) # Qingming begins when the sun reaches the celestial # longitude of 15° (usually around April 4th or 5th) qingming = solar_term(year, 15, 'Asia/Taipei') days.extend([ ( ChineseNewYearCalendar.lunar(year, 1, 3), "Chinese New Year (3rd day)" ), (qingming, "Qingming Festival"), (ChineseNewYearCalendar.lunar(year, 5, 5), "Dragon Boat Festival"), (ChineseNewYearCalendar.lunar(year, 8, 15), "Mid-Autumn Festival"), ]) return days calendra-7.9.0/calendra/astronomy.py000066400000000000000000000004511457013633400174640ustar00rootroot00000000000000try: import skyfield # noqa: F401 import skyfield_data # noqa: F401 from .skyfield_astronomy import calculate_equinoxes, solar_term except ImportError: from .precomputed_astronomy import calculate_equinoxes, solar_term __all__ = [ 'calculate_equinoxes', 'solar_term', ] calendra-7.9.0/calendra/core.py000066400000000000000000001101721457013633400163630ustar00rootroot00000000000000""" Working day tools """ import warnings from calendar import monthrange from datetime import date, timedelta, datetime from pathlib import Path import sys import convertdate from dateutil import easter from lunardate import LunarDate from dateutil import relativedelta as rd from .exceptions import ( UnsupportedDateType, CalendarError, ICalExportRangeError, ICalExportTargetPathError ) from . import __version__ from .holiday import Holiday, SeriesShiftMixin MON, TUE, WED, THU, FRI, SAT, SUN = range(7) ISO_MON, ISO_TUE, ISO_WED, ISO_THU, ISO_FRI, ISO_SAT, ISO_SUN = range(1, 8) class classproperty: def __init__(self, getter): self.getter = getter self.__doc__ = getter.__doc__ def __get__(self, instance, owner): return self.getter(owner) def cleaned_date(day, keep_datetime=False): """ Return a "clean" date type. * keep a `date` unchanged * convert a datetime into a date, * convert any "duck date" type into a date using its `date()` method. """ if not isinstance(day, (date, datetime)): raise UnsupportedDateType( f"`{day}` is of unsupported type ({type(day)})" ) if not keep_datetime: if hasattr(day, 'date') and callable(day.date): day = day.date() return day def daterange(start, end): """ Yield days from ``start`` to ``end`` including both of them. If start and end are in opposite order, they'll be swapped silently. """ # Swap if necessary if start > end: end, start = start, end day = start while day <= end: yield day day += timedelta(days=1) class ChristianMixin: EASTER_METHOD = None # to be assigned in the inherited mixin include_epiphany = False include_clean_monday = False include_annunciation = False include_fat_tuesday = False # Fat tuesday forced to `None` to make sure this value is always set # We've seen that there was a wide variety of labels. fat_tuesday_label = None include_ash_wednesday = False ash_wednesday_label = "Ash Wednesday" include_palm_sunday = False include_holy_thursday = False holy_thursday_label = "Holy Thursday" include_good_friday = False good_friday_label = "Good Friday" include_easter_monday = False include_easter_saturday = False easter_saturday_label = "Easter Saturday" include_easter_sunday = False include_all_saints = False include_immaculate_conception = False immaculate_conception_label = "Immaculate Conception" include_christmas = True include_christmas_eve = False include_ascension = False include_assumption = False include_whit_sunday = False whit_sunday_label = 'Whit Sunday' include_whit_monday = False whit_monday_label = 'Whit Monday' include_corpus_christi = False include_boxing_day = False boxing_day_label = "Boxing Day" include_all_souls = False def get_fat_tuesday(self, year): if not self.fat_tuesday_label: raise CalendarError( "Improperly configured: please provide a " "`fat_tuesday_label` value") sunday = self.get_easter_sunday(year) return sunday - timedelta(days=47) def get_ash_wednesday(self, year): sunday = self.get_easter_sunday(year) return sunday - timedelta(days=46) def get_palm_sunday(self, year): sunday = self.get_easter_sunday(year) return sunday - timedelta(days=7) def get_holy_thursday(self, year): "Return the date of the last thursday before easter" sunday = self.get_easter_sunday(year) return sunday - timedelta(days=3) def get_good_friday(self, year): "Return the date of the last friday before easter" sunday = self.get_easter_sunday(year) return sunday - timedelta(days=2) def get_clean_monday(self, year): "Return the clean monday date" sunday = self.get_easter_sunday(year) return sunday - timedelta(days=48) def get_easter_saturday(self, year): "Return the Easter Saturday date" sunday = self.get_easter_sunday(year) return sunday - timedelta(days=1) def get_easter_sunday(self, year): "Return the date of the easter (sunday) -- following the easter method" return easter.easter(year, self.EASTER_METHOD) def get_easter_monday(self, year): "Return the date of the monday after easter" sunday = self.get_easter_sunday(year) return sunday + timedelta(days=1) def get_ascension_thursday(self, year): easter = self.get_easter_sunday(year) return easter + timedelta(days=39) def get_whit_monday(self, year): easter = self.get_easter_sunday(year) return easter + timedelta(days=50) def get_whit_sunday(self, year): easter = self.get_easter_sunday(year) return easter + timedelta(days=49) def get_corpus_christi(self, year): return self.get_easter_sunday(year) + timedelta(days=60) def get_variable_days(self, year): # noqa "Return the christian holidays list according to the mixin" days = super().get_variable_days(year) if self.include_epiphany: days.append((date(year, 1, 6), "Epiphany")) if self.include_clean_monday: days.append((self.get_clean_monday(year), "Clean Monday")) if self.include_annunciation: days.append((date(year, 3, 25), "Annunciation")) if self.include_fat_tuesday: days.append( (self.get_fat_tuesday(year), self.fat_tuesday_label) ) if self.include_ash_wednesday: days.append( (self.get_ash_wednesday(year), self.ash_wednesday_label) ) if self.include_palm_sunday: days.append((self.get_palm_sunday(year), "Palm Sunday")) if self.include_holy_thursday: days.append( (self.get_holy_thursday(year), self.holy_thursday_label) ) if self.include_good_friday: days.append((self.get_good_friday(year), self.good_friday_label)) if self.include_easter_saturday: days.append( (self.get_easter_saturday(year), self.easter_saturday_label) ) if self.include_easter_sunday: days.append((self.get_easter_sunday(year), "Easter Sunday")) if self.include_easter_monday: days.append((self.get_easter_monday(year), "Easter Monday")) if self.include_assumption: days.append((date(year, 8, 15), "Assumption of Mary to Heaven")) if self.include_all_saints: days.append((date(year, 11, 1), "All Saints Day")) if self.include_all_souls: days.append((date(year, 11, 2), "All Souls Day")) if self.include_immaculate_conception: days.append((date(year, 12, 8), self.immaculate_conception_label)) christmas = None if self.include_christmas: christmas = Holiday(date(year, 12, 25), "Christmas Day") days.append(christmas) if self.include_christmas_eve: days.append((date(year, 12, 24), "Christmas Eve")) if self.include_boxing_day: boxing_day = Holiday( date(year, 12, 26), self.boxing_day_label, indication="Day after Christmas", ) days.append(boxing_day) if self.include_ascension: days.append(( self.get_ascension_thursday(year), "Ascension Thursday")) if self.include_whit_monday: days.append((self.get_whit_monday(year), self.whit_monday_label)) if self.include_whit_sunday: days.append((self.get_whit_sunday(year), self.whit_sunday_label)) if self.include_corpus_christi: days.append((self.get_corpus_christi(year), "Corpus Christi")) return days class WesternMixin(ChristianMixin): """ General usage calendar for Western countries. (chiefly Europe and Northern America) """ EASTER_METHOD = easter.EASTER_WESTERN WEEKEND_DAYS = (SAT, SUN) include_new_years_day = False shift_new_years_day = False def get_variable_days(self, year): days = super().get_variable_days(year) new_years = Holiday( date(year, 1, 1), 'New year', indication='First day in January', ) if not self.shift_new_years_day: new_years.observance_shift = None days.append(new_years) return days class OrthodoxMixin(ChristianMixin): EASTER_METHOD = easter.EASTER_ORTHODOX WEEKEND_DAYS = (SAT, SUN) include_orthodox_christmas = True # This label should be de-duplicated if needed orthodox_christmas_day_label = "Christmas" def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.include_orthodox_christmas: days.append( (date(year, 1, 7), self.orthodox_christmas_day_label) ) return days class LunarMixin: """ Calendar ready to compute luncar calendar days """ @staticmethod def lunar(year, month, day): return LunarDate(year, month, day).toSolarDate() class ChineseNewYearMixin(LunarMixin): """ Calendar including toolsets to compute the Chinese New Year holidays. """ include_chinese_new_year_eve = False chinese_new_year_eve_label = "Chinese New Year's eve" # Chinese New Year will be included by default include_chinese_new_year = True chinese_new_year_label = 'Chinese New Year' # Some countries include the 2nd lunar day as a holiday include_chinese_second_day = False chinese_second_day_label = "Chinese New Year (2nd day)" include_chinese_third_day = False chinese_third_day_label = "Chinese New Year (3rd day)" shift_sunday_holidays = False # Some calendars roll a starting Sunday CNY to Sat shift_start_cny_sunday = False def get_chinese_new_year(self, year): """ Compute Chinese New Year days. To return a list of holidays. By default, it'll at least return the Chinese New Year holidays chosen using the following options: * ``include_chinese_new_year_eve`` * ``include_chinese_new_year`` (on by default) * ``include_chinese_second_day`` If the ``shift_sunday_holidays`` option is on, the rules are the following. * If the CNY1 falls on MON-FRI, there's not shift. * If the CNY1 falls on SAT, the CNY2 is shifted to the Monday after. * If the CNY1 falls on SUN, the CNY1 is shifted to the Monday after, and CNY2 is shifted to the Tuesday after. """ days = [] lunar_first_day = ChineseNewYearMixin.lunar(year, 1, 1) # Chinese new year's eve if self.include_chinese_new_year_eve: days.append(( lunar_first_day - timedelta(days=1), self.chinese_new_year_eve_label )) # Chinese new year (is included by default) if self.include_chinese_new_year: days.append((lunar_first_day, self.chinese_new_year_label)) if self.include_chinese_second_day: lunar_second_day = lunar_first_day + timedelta(days=1) days.append(( lunar_second_day, self.chinese_second_day_label )) if self.include_chinese_third_day: lunar_third_day = lunar_first_day + timedelta(days=2) days.append(( lunar_third_day, self.chinese_third_day_label )) if self.shift_sunday_holidays: if lunar_first_day.weekday() == SUN: if self.shift_start_cny_sunday: days.append( (lunar_first_day - timedelta(days=1), "Chinese Lunar New Year shift"), ) else: if self.include_chinese_third_day: shift_day = lunar_third_day else: shift_day = lunar_second_day days.append( (shift_day + timedelta(days=1), "Chinese Lunar New Year shift"), ) if (lunar_second_day.weekday() == SUN and self.include_chinese_third_day): days.append( (lunar_third_day + timedelta(days=1), "Chinese Lunar New Year shift"), ) return days def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_chinese_new_year(year)) return days @staticmethod def observance_shift(holiday, calendar): """ Taking an existing holiday, return a 'shifted' day to skip on from SUN. """ do_shift = calendar.shift_sunday_holidays and holiday.weekday() == SUN return holiday + timedelta(days=1) * do_shift class CalverterMixin: conversion_method = None ISLAMIC_HOLIDAYS = () def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.conversion_method is None: raise NotImplementedError def converted(self, year): current = date(year, 1, 1) delta = timedelta(days=1) days = [] while current.year == year: days.append( self.conversion_method.from_gregorian( current.year, current.month, current.day ) ) current += delta return days def calverted_years(self, year): converted = self.converted(year) return sorted({y for y, m, d in converted}) def get_islamic_holidays(self): return self.ISLAMIC_HOLIDAYS def get_delta_islamic_holidays(self, year): """ Return the delta to add/substract according to the year or customs. By default, to return None or timedelta(days=0) """ return None def get_variable_days(self, year): warnings.warn('Please take note that, due to arbitrary decisions, ' 'this Islamic calendar computation may be wrong.') days = super().get_variable_days(year) years = self.calverted_years(year) for month, day, label in self.get_islamic_holidays(): for y in years: g_date = self.conversion_method.to_gregorian(y, month, day) holiday = date(*g_date) # Only add a delta if necessary delta = self.get_delta_islamic_holidays(year) if delta: holiday += delta if holiday.year == year: days.append((holiday, label)) return days class IslamicMixin(CalverterMixin): WEEKEND_DAYS = (FRI, SAT) conversion_method = convertdate.islamic include_prophet_birthday = False include_day_after_prophet_birthday = False include_start_ramadan = False include_eid_al_fitr = False length_eid_al_fitr = 1 eid_al_fitr_label = "Eid al-Fitr" include_eid_al_adha = False eid_al_adha_label = "Eid al-Adha" length_eid_al_adha = 1 include_day_of_sacrifice = False day_of_sacrifice_label = "Eid al-Adha" include_islamic_new_year = False include_laylat_al_qadr = False include_nuzul_al_quran = False def get_islamic_holidays(self): # noqa: C901 """Return a list of Islamic (month, day, label) for islamic holidays. Please take note that these dates must be expressed using the Islamic Calendar""" days = list(super().get_islamic_holidays()) if self.include_islamic_new_year: days.append((1, 1, "Islamic New Year")) if self.include_prophet_birthday: days.append((3, 12, "Prophet's Birthday")) if self.include_day_after_prophet_birthday: days.append((3, 13, "Day after Prophet's Birthday")) if self.include_start_ramadan: days.append((9, 1, "Start of ramadan")) if self.include_nuzul_al_quran: days.append((9, 17, "Nuzul Al-Qur'an")) if self.include_eid_al_fitr: for x in range(self.length_eid_al_fitr): days.append((10, x + 1, self.eid_al_fitr_label)) if self.include_eid_al_adha: for x in range(self.length_eid_al_adha): days.append((12, x + 10, self.eid_al_adha_label)) if self.include_day_of_sacrifice: days.append((12, 10, self.day_of_sacrifice_label)) if self.include_laylat_al_qadr: warnings.warn("The Islamic holiday named Laylat al-Qadr is decided" " by the religious authorities. It is not possible" " to compute it. You'll have to add it manually.") return tuple(days) class CoreCalendar: FIXED_HOLIDAYS = () WEEKEND_DAYS = () observance_shift = dict(weekday=rd.MO(1)) """ The shift for the observance of a holiday defined as keyword parameters to a rd.relativedelta instance. By default, holidays are shifted to the Monday following the weekend. """ def __init__(self): self._holidays = {} @classproperty def name(cls): class_name = cls.__name__ if cls.__doc__: doc = cls.__doc__.split('\n') doc = map(lambda s: s.strip(), doc) return next(s for s in doc if s) return class_name def get_fixed_holidays(self, year): """Return the fixed days according to the FIXED_HOLIDAYS class property """ fixed_holidays = map( Holiday._from_fixed_definition, self.FIXED_HOLIDAYS, ) return [day.replace(year=year) for day in fixed_holidays] def get_variable_days(self, year): return [] def get_calendar_holidays(self, year): """Get calendar holidays. If you want to override this, please make sure that it **must** return a list of tuples (date, holiday_name).""" return self.get_fixed_holidays(year) + self.get_variable_days(year) def holidays(self, year=None): """Computes holidays (non-working days) for a given year. Return a 2-item tuple, composed of the date and a label.""" if not year: year = date.today().year if year in self._holidays: return self._holidays[year] # Here we process the holiday specific calendar days = self.get_calendar_holidays(year) days = map(Holiday._from_resolved_definition, days) temp_calendar = tuple(days) # it is sorted self._holidays[year] = sorted(temp_calendar) return self._holidays[year] def get_holiday_label(self, day): """Return the label of the holiday, if the date is a holiday""" day = cleaned_date(day) return {day: label for day, label in self.holidays(day.year)}.get(day) def holidays_set(self, year=None): "Return a quick date index (set)" return set(self.holidays(year)) def get_weekend_days(self): """Return a list (or a tuple) of weekdays that are *not* working days. e.g: return (SAT, SUN,) """ if self.WEEKEND_DAYS: return self.WEEKEND_DAYS else: raise NotImplementedError("Your Calendar class must provide " "WEEKEND_DAYS or implement the " "`get_weekend_days` method") def is_working_day(self, day, extra_working_days=None, extra_holidays=None): """Return True if it's a working day. In addition to the regular holidays, you can add exceptions. By providing ``extra_working_days``, you'll state that these dates **are** working days. By providing ``extra_holidays``, you'll state that these dates **are** holidays, even if not in the regular calendar holidays (or weekends). Please note that the ``extra_working_days`` list has priority over the ``extra_holidays`` list. """ day = cleaned_date(day) if extra_working_days: extra_working_days = tuple(map(cleaned_date, extra_working_days)) if extra_holidays: extra_holidays = tuple(map(cleaned_date, extra_holidays)) # Extra lists exceptions if extra_working_days and day in extra_working_days: return True # Regular rules if day.weekday() in self.get_weekend_days(): return False if extra_holidays and day in extra_holidays: return False return not self.is_observed_holiday(day) def is_holiday(self, day, extra_holidays=None): """Return True if it's an holiday. In addition to the regular holidays, you can add exceptions. By providing ``extra_holidays``, you'll state that these dates **are** holidays, even if not in the regular calendar holidays (or weekends). """ day = cleaned_date(day) if extra_holidays: extra_holidays = tuple(map(cleaned_date, extra_holidays)) if extra_holidays and day in extra_holidays: return True return day in self.holidays_set(day.year) def observed_holidays(self, year): return set( holiday.get_observed_date(self) for holiday in self.holidays(year) ) def is_observed_holiday(self, day): """Return True if it's an observed holiday. """ return day in self.observed_holidays(day.year) def add_working_days(self, day, delta, extra_working_days=None, extra_holidays=None, keep_datetime=False): """Add `delta` working days to the date. You can provide either a date or a datetime to this function that will output a ``date`` result. You can alter this behaviour using the ``keep_datetime`` option set to ``True``. the ``delta`` parameter might be positive or negative. If it's negative, you may want to use the ``sub_working_days()`` method with a positive ``delta`` argument. By providing ``extra_working_days``, you'll state that these dates **are** working days. By providing ``extra_holidays``, you'll state that these dates **are** holidays, even if not in the regular calendar holidays (or weekends). Please note that the ``extra_working_days`` list has priority over the ``extra_holidays`` list. """ day = cleaned_date(day, keep_datetime) if extra_working_days: extra_working_days = tuple(map(cleaned_date, extra_working_days)) if extra_holidays: extra_holidays = tuple(map(cleaned_date, extra_holidays)) days = 0 temp_day = day day_added = 1 if delta >= 0 else -1 delta = abs(delta) while days < delta: temp_day = temp_day + timedelta(days=day_added) if self.is_working_day(temp_day, extra_working_days=extra_working_days, extra_holidays=extra_holidays): days += 1 return temp_day def sub_working_days(self, day, delta, extra_working_days=None, extra_holidays=None, keep_datetime=False): """ Substract `delta` working days to the date. This method is a shortcut / helper. Users may want to use either:: cal.add_working_days(my_date, -7) cal.sub_working_days(my_date, 7) The other parameters are to be used exactly as in the ``add_working_days`` method. A negative ``delta`` argument will be converted into its absolute value. Hence, the two following calls are equivalent:: cal.sub_working_days(my_date, -7) cal.sub_working_days(my_date, 7) As in ``add_working_days()`` you can set the parameter ``keep_datetime`` to ``True`` to make sure that if your ``day`` argument is a ``datetime``, the returned date will also be a ``datetime`` object. """ delta = abs(delta) return self.add_working_days( day, -delta, extra_working_days, extra_holidays, keep_datetime=keep_datetime) def find_following_working_day(self, day): """Looks for the following working day, if not already a working day. **WARNING**: this function doesn't take into account the calendar holidays, only the days of the week and the weekend days parameters. """ day = cleaned_date(day) while day.weekday() in self.get_weekend_days(): day = day + timedelta(days=1) return day @staticmethod def get_nth_weekday_in_month(year, month, weekday, n=1, start=None): """Get the nth weekday in a given month. e.g: >>> # the 1st monday in Jan 2013 >>> Calendar.get_nth_weekday_in_month(2013, 1, MON) datetime.date(2013, 1, 7) >>> # The 2nd monday in Jan 2013 >>> Calendar.get_nth_weekday_in_month(2013, 1, MON, 2) datetime.date(2013, 1, 14) """ # If start is `None` or Falsy, no need to check and clean if start: start = cleaned_date(start) day = date(year, month, 1) if start: day = start counter = 0 while True: if day.month != month: # Don't forget to break if "n" is too big return None if day.weekday() == weekday: counter += 1 if counter == n: break day = day + timedelta(days=1) return day @staticmethod def get_last_weekday_in_month(year, month, weekday): """Get the last weekday in a given month. e.g: >>> # the last monday in Jan 2013 >>> Calendar.get_last_weekday_in_month(2013, 1, MON) datetime.date(2013, 1, 28) """ day = date(year, month, monthrange(year, month)[1]) while True: if day.weekday() == weekday: break day = day - timedelta(days=1) return day @staticmethod def get_iso_week_date(year, week_nb, weekday=ISO_MON): """ Return the date of the weekday of the week number (ISO definition). **Warning:** in the ISO definition, the weeks start on MON, not SUN. By default, if you don't provide the ``weekday`` argument, it'll return the date of the MON of this week number. Example: >>> Calendar.get_iso_week_date(2021, 44) datetime.date(2021, 11, 1) For your convenience, the ISO weekdays are available via the ``calendra.core`` module, like this: from calendra.core import ISO_MON, ISO_TUE # etc. i.e.: if you need to get the FRI of the week 44 of the year 2020, you'll have to use: from calendra.core import ISO_FRI Calendar.get_iso_week_date(2020, 44, ISO_FRI) """ if sys.version_info >= (3, 8, 0): # use the stock Python 3.8 function return date.fromisocalendar(year, week_nb, weekday) # else, use the backport # Adapted from https://stackoverflow.com/a/59200842 jan_1st = date(year, 1, 1) _, jan_1st_week, jan_1st_weekday = jan_1st.isocalendar() base = 1 if jan_1st_week == 1 else 8 delta = base - jan_1st_weekday + 7 * (week_nb - 1) + (weekday - 1) start = jan_1st + timedelta(days=delta) return start @staticmethod def get_first_weekday_after(day, weekday): """Get the first weekday after a given day. If the day is the same weekday, the same day will be returned. >>> # the first monday after Apr 1 2015 >>> Calendar.get_first_weekday_after(date(2015, 4, 1), MON) datetime.date(2015, 4, 6) >>> # the first tuesday after Apr 14 2015 >>> Calendar.get_first_weekday_after(date(2015, 4, 14), TUE) datetime.date(2015, 4, 14) """ day_delta = (weekday - day.weekday()) % 7 day = day + timedelta(days=day_delta) return day def get_working_days_delta(self, start, end, include_start=False, extra_working_days=None, extra_holidays=None): """ Return the number of working day between two given dates. The order of the dates provided doesn't matter. In the following example, there are 5 days, because of the week-end: >>> cal = WesternCalendar() # does not include easter monday >>> day1 = date(2018, 3, 29) >>> day2 = date(2018, 4, 5) >>> cal.get_working_days_delta(day1, day2) 5 In France, April 1st 2018 is a holiday because it's Easter monday: >>> from calendra.europe import France >>> cal = France() >>> cal.get_working_days_delta(day1, day2) 4 This method should even work if your ``start`` and ``end`` arguments are datetimes. By default, if the day after you start is not a working day, the count will start at 0. If include_start is set to true, this day will be taken into account. Example: >>> from dateutil.parser import parse >>> cal = France() >>> day1 = parse('09/05/2018 00:01', dayfirst=True) >>> day2 = parse('10/05/2018 19:01', dayfirst=True) # holiday in france >>> cal.get_working_days_delta(day1, day2) 0 >>> cal.get_working_days_delta(day1, day2, include_start=True) 1 As in many other methods, you can use the ``extra_holidays`` and ``extra_working_days`` to exclude """ start = cleaned_date(start) end = cleaned_date(end) if start == end: return 0 if start > end: start, end = end, start # Starting count here is_working_day = self.is_working_day( start, extra_working_days=extra_working_days, extra_holidays=extra_holidays ) count = 1 if include_start and is_working_day else 0 while start < end: start += timedelta(days=1) is_working_day = self.is_working_day( start, extra_working_days=extra_working_days, extra_holidays=extra_holidays ) if is_working_day: count += 1 return count def _get_ical_period(self, period=None): """ Return a usable period for iCal export Default period is [2000, 2030] """ # Default value. if not period: period = [2000, 2030] # Make sure it's a usable iterable if type(period) not in (list, tuple): raise ICalExportRangeError( "Incorrect Range type. Must be list or tuple.") # Taking the extremes period = [min(period), max(period)] # check for internal types check_types = map(type, period) check_types = map(lambda x: x != int, check_types) if any(check_types): raise ICalExportRangeError( "Incorrect Range boundaries. Must be int.") return period def _get_ical_target_path(self, target_path): """ Return target path for iCal export. Note ---- If `target_path` does not have one of the extensions `.ical`, `.ics`, `.ifb`, or `.icalendar`, the extension `.ics` is appended to the path. Returns ------- None. Examples -------- >>> from calendra.europe import Austria >>> cal = Austria() >>> str(cal._get_ical_target_path('austria')) 'austria.ics' """ if not target_path: raise ICalExportTargetPathError( "Incorrect target path. It must not be empty") target_path = Path(target_path) if target_path.is_dir(): raise ICalExportTargetPathError( "Incorrect target path. It must not be a directory" ) ical_extensions = ['.ical', '.ics', '.ifb', '.icalendar'] if target_path.suffix not in ical_extensions: target_path = target_path.with_name(target_path.name + '.ics') return target_path def export_to_ical(self, period=[2000, 2030], target_path=None): """ Export the calendar to iCal (RFC 5545) format. Parameters ---------- period: [int, int] start and end year (inclusive) of calendar Default is [2000, 2030] target_path: str or pathlib.Path the name or path of the exported file. If this argument is missing, the function will return the ical content. """ first_year, last_year = self._get_ical_period(period) if target_path: # Generate filename path before calculate the holidays target_path = self._get_ical_target_path(target_path) # fetch holidays holidays = [] for year in range(first_year, last_year + 1): holidays.extend(self.holidays(year)) # initialize icalendar ics = [ 'BEGIN:VCALENDAR', 'VERSION:2.0', # current RFC5545 version f'PRODID:-//workalendar//ical {__version__}//EN' ] dtstamp = f'DTSTAMP;VALUE=DATE-TIME:{datetime.utcnow():%Y%m%dT%H%M%SZ}' # add an event for each holiday for holiday in holidays: date_ = holiday.get_observed_date(self) ics.extend([ 'BEGIN:VEVENT', f'SUMMARY:{holiday.name}', f'DTSTART;VALUE=DATE:{date_:%Y%m%d}', dtstamp, f'UID:{date_}{holiday.name}@peopledoc.github.io/workalendar', 'END:VEVENT', ]) # add footer ics.append('END:VCALENDAR\n') # last line with a trailing \n # Transform this list into text lines ics = "\n".join(ics) if target_path: # save iCal file with target_path.open('w+') as export_file: export_file.write(ics) return return ics class Calendar(SeriesShiftMixin, CoreCalendar): """ The cornerstone of Earth calendars. Take care of the New Years Day, which is almost a worldwide holiday. """ include_new_years_day = True include_new_years_eve = False shift_new_years_day = False include_labour_day = False labour_day_label = "Labour Day" def __init__(self, **kwargs): super().__init__() def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.include_new_years_day: days.insert(0, (date(year, 1, 1), "New year")) if self.include_new_years_eve: days.append((date(year, 12, 31), "New Year's eve")) if self.include_labour_day: days.append((date(year, 5, 1), self.labour_day_label)) return days def get_variable_days(self, year): days = super().get_variable_days(year) new_year = date(year, 1, 1) if self.include_new_years_day and self.shift_new_years_day: if new_year.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(new_year), "New Year shift")) return days class WesternCalendar(WesternMixin, Calendar): """ A Christian calendar using Western definition for Easter. """ class OrthodoxCalendar(OrthodoxMixin, Calendar): """ A Christian calendar using Orthodox definition for Easter. """ class ChineseNewYearCalendar(ChineseNewYearMixin, Calendar): """ Chinese Calendar, using Chinese New Year computation. """ # There are regional exceptions to those week-end days, to define locally. WEEKEND_DAYS = (SAT, SUN) class IslamicCalendar(IslamicMixin, Calendar): """ Islamic calendar """ class IslamoWesternCalendar(IslamicMixin, WesternMixin, Calendar): """ Mix of Islamic and Western calendars. When countries have both Islamic and Western-Christian holidays. """ FIXED_HOLIDAYS = Calendar.FIXED_HOLIDAYS calendra-7.9.0/calendra/create-astronomical-data.py000077500000000000000000000002221457013633400222730ustar00rootroot00000000000000from tqdm import tqdm from .precomputed_astronomy import create_astronomical_data if __name__ == '__main__': create_astronomical_data(tqdm) calendra-7.9.0/calendra/equinoxes.json.gz000066400000000000000000000014111457013633400204060ustar00rootroot00000000000000`equinoxes.jsonAkQFdmi$w .u'"AJ b#FJ7^K#()3pjqn{_xvqۛNrxmnߦa*@47ʔ@T*PS Ԋ7MAImLm@mxhj5 wG,]vp+e&eAaݧ''ݧ''wvptvp}}}}}}ri Ii ݧ仟y''w/܋e{q{e{ѽ^p/^ve{q{a{ٽ^}}-W}}}qeݗw_v_ //////ྸ~&ׇW?BG IBBG IBBG IBBG IBB($5 )VHjR(8Z!QHBRhBRhBRRH*$5 )z i:!BRRH*$5 )z i_F!EO!Mg=}!QHBҟ i: I]{f|hΣ9= 2020: days.extend([ # Statehood date has changed in 2020 (date(year, 5, 30), "Statehood Day"), # Remembrance Day has been added in 2020 (date(year, 11, 18), "Remembrance Day"), ]) else: days.extend([ (date(year, 6, 25), "Statehood Day"), # Independance day was a holiday until 2020 (date(year, 10, 8), "Independence Day"), ]) return days calendra-7.9.0/calendra/europe/cyprus.py000066400000000000000000000021241457013633400202540ustar00rootroot00000000000000from datetime import timedelta from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('CY') class Cyprus(WesternCalendar): 'Cyprus' # Civil holidays include_labour_day = True # Christian holidays include_epiphany = True include_clean_monday = True include_good_friday = True include_easter_saturday = True include_easter_sunday = True include_easter_monday = True include_whit_monday = True whit_monday_label = 'Pentecost Monday' include_christmas_eve = True include_christmas_day = True include_boxing_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (3, 25, "Greek Independence Day"), (4, 1, "Cyprus National Day"), (7, 15, "Dormition of the Theotokos"), (10, 1, "Cyprus Independence Day"), (10, 28, "Greek National Day"), ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append((self.get_easter_monday(year) + timedelta(days=1), "Easter Tuesday")) return days calendra-7.9.0/calendra/europe/czech_republic.py000066400000000000000000000017611457013633400217160ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('CZ') class CzechRepublic(WesternCalendar): 'Czech Republic' # Civil holidays include_labour_day = True # Christian holidays include_easter_monday = True include_good_friday = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 1, "Restoration Day of the Independent Czech State"), (5, 8, "Liberation Day"), (7, 5, "Saints Cyril and Methodius Day"), (7, 6, "Jan Hus Day"), (9, 28, "St. Wenceslas Day (Czech Statehood Day)"), (10, 28, "Independent Czechoslovak State Day"), (11, 17, "Struggle for Freedom and Democracy Day"), (12, 24, "Christmas Eve"), (12, 26, "St. Stephen's Day (The Second Christmas Day)"), ) def get_variable_days(self, year): # As of 2016, Good Friday became a holiday self.include_good_friday = (year >= 2016) return super().get_variable_days(year) calendra-7.9.0/calendra/europe/denmark.py000066400000000000000000000016511457013633400203540ustar00rootroot00000000000000from datetime import timedelta from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('DK') class Denmark(WesternCalendar): 'Denmark' include_holy_thursday = True include_good_friday = True include_easter_sunday = True include_easter_monday = True include_ascension = True include_whit_sunday = True whit_sunday_label = "Pentecost Sunday" include_whit_monday = True whit_monday_label = "Pentecost Monday" include_boxing_day = True boxing_day_label = "Second Day of Christmas" include_christmas_eve = True def get_store_bededag(self, year): # 'great prayer day' easter_sunday = self.get_easter_sunday(year) return easter_sunday + timedelta(days=26) def get_variable_days(self, year): days = super().get_variable_days(year) days.append((self.get_store_bededag(year), "Store Bededag")) return days calendra-7.9.0/calendra/europe/estonia.py000066400000000000000000000012211457013633400203660ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('EE') class Estonia(WesternCalendar): 'Estonia' include_good_friday = True include_easter_sunday = True include_whit_sunday = True whit_sunday_label = 'Nelipühade 1. püha' include_christmas_eve = True include_christmas = True include_boxing_day = True boxing_day_label = "Teine jõulupüha" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 24, "Independence Day"), (5, 1, "Kevadpüha"), (6, 23, "Võidupüha"), (6, 24, "Jaanipäev"), (8, 20, "Taasiseseisvumispäev") ) calendra-7.9.0/calendra/europe/european_central_bank.py000066400000000000000000000005371457013633400232560ustar00rootroot00000000000000from ..core import WesternCalendar class EuropeanCentralBank(WesternCalendar): "European Central Bank" # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (12, 26, "St. Stephen's Day"), ) # Christian holidays include_good_friday = True include_easter_monday = True calendra-7.9.0/calendra/europe/finland.py000066400000000000000000000031141457013633400203420ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, FRI, SAT from ..registry_tools import iso_register @iso_register('FI') class Finland(WesternCalendar): 'Finland' # Christian holidays include_epiphany = True include_good_friday = True include_easter_sunday = True include_easter_monday = True include_ascension = True include_whit_sunday = True whit_sunday_label = 'Pentecost' include_christmas_eve = True include_boxing_day = True boxing_day_label = "St. Stephen's Day" observance_shift = None # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (12, 6, "Independence Day"), ) def get_midsummer_eve(self, year): date_eve = Finland.get_nth_weekday_in_month( year, 6, FRI, start=date(year, 6, 19)) return date_eve def get_midsummer_day(self, year): date_eve = Finland.get_nth_weekday_in_month( year, 6, SAT, start=date(year, 6, 20)) return date_eve def get_variable_all_saints(self, year): all_saints = date(year, 10, 31) if all_saints.weekday() != SAT: all_saints = Finland.get_nth_weekday_in_month( year, 11, SAT) return all_saints def get_variable_days(self, year): days = super().get_variable_days(year) days.append((self.get_midsummer_eve(year), "Midsummer's Eve")) days.append((self.get_midsummer_day(year), "Midsummer's Day")) days.append((self.get_variable_all_saints(year), "All Saints")) return days calendra-7.9.0/calendra/europe/france.py000066400000000000000000000012371457013633400201710ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('FR') class France(WesternCalendar): 'France' # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_all_saints = True include_assumption = True # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 8, "Victory in Europe Day"), (7, 14, "Bastille Day"), (11, 11, "Armistice Day"), ) class FranceAlsaceMoselle(France): "France Alsace/Moselle" include_good_friday = True include_boxing_day = True calendra-7.9.0/calendra/europe/georgia.py000066400000000000000000000021421457013633400203440ustar00rootroot00000000000000from ..core import OrthodoxCalendar from ..registry_tools import iso_register @iso_register('GE') class Georgia(OrthodoxCalendar): 'Country of Georgia' "Sources: " "https://en.wikipedia.org/wiki/Public_holidays_in_Georgia_(country)" "https://www.officeholidays.com/countries/georgia/2021" include_christmas = False include_christmas_eve = False include_new_years_day = True include_orthodox_christmas = True include_epiphany = False include_good_friday = True include_easter_saturday = True include_easter_sunday = True include_easter_monday = True FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (1, 2, "Day After New Year"), (1, 19, "Orthodox Epiphany"), (3, 3, "Mother's Day"), (3, 8, "International Women's Day"), (4, 9, "Day Of National Unity"), (5, 9, "Day Of Victory Over Fascism"), (5, 12, "Saint Andrew The First-Called Day"), (5, 26, "Independence Day"), (8, 28, "Saint Mary's Day"), (10, 14, "Day Of Svetitskovloba"), (11, 23, "Saint George's Day"), ) calendra-7.9.0/calendra/europe/germany.py000066400000000000000000000107551457013633400204020ustar00rootroot00000000000000from datetime import date, timedelta from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('DE') class Germany(WesternCalendar): 'Germany' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (10, 3, "Day of German Unity"), ) # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_good_friday = True include_boxing_day = True boxing_day_label = "Second Christmas Day" # True if including reformation day for all years all_time_include_reformation_day = False # True if including reformation day since 2018 include_reformation_day_2018 = False def include_reformation_day(self, year): """ Return True if the Reformation Day is a holiday. """ if self.all_time_include_reformation_day or year == 2017: return True if self.include_reformation_day_2018 and year >= 2018: return True return False def get_reformation_day(self, year): """ Reformation Day is a fixed date. It's handled via the variable_days because it can be activated depending on the Länder or the year (see #150). """ day = date(year, 10, 31) return day, "Reformation Day" def get_variable_days(self, year): days = super().get_variable_days(year) if self.include_reformation_day(year): days.append(self.get_reformation_day(year)) return days @iso_register('DE-BW') class BadenWurttemberg(Germany): "Baden-Wuerttemberg" include_epiphany = True include_corpus_christi = True include_all_saints = True @iso_register('DE-BY') class Bavaria(Germany): 'Bavaria' include_epiphany = True include_corpus_christi = True include_all_saints = True include_assumption = True @iso_register('DE-BE') class Berlin(Germany): 'Berlin' def get_international_womens_day(self, year): day = date(year, 3, 8) return day, "International Women's Day" def get_liberation_day(self, year): day = date(year, 5, 8) return day, "Liberation Day" def get_variable_days(self, year): days = super().get_variable_days(year) if year >= 2019: days.append(self.get_international_womens_day(year)) if year == 2020: days.append(self.get_liberation_day(year)) return days @iso_register('DE-BB') class Brandenburg(Germany): 'Brandenburg' include_easter_sunday = True all_time_include_reformation_day = True @iso_register('DE-HB') class Bremen(Germany): 'Bremen' include_reformation_day_2018 = True @iso_register('DE-HH') class Hamburg(Germany): 'Hamburg' include_reformation_day_2018 = True @iso_register('DE-HE') class Hesse(Germany): 'Hesse' include_corpus_christi = True @iso_register('DE-MV') class MecklenburgVorpommern(Germany): 'Mecklenburg-Western Pomerania' all_time_include_reformation_day = True @iso_register('DE-NI') class LowerSaxony(Germany): 'Lower Saxony' include_reformation_day_2018 = True @iso_register('DE-NW') class NorthRhineWestphalia(Germany): 'North Rhine-Westphalia' include_corpus_christi = True include_all_saints = True @iso_register('DE-RP') class RhinelandPalatinate(Germany): 'Rhineland-Palatinate' include_corpus_christi = True include_all_saints = True @iso_register('DE-SL') class Saarland(Germany): 'Saarland' include_corpus_christi = True include_assumption = True include_all_saints = True @iso_register('DE-SN') class Saxony(Germany): 'Saxony' all_time_include_reformation_day = True def get_repentance_day(self, year): "Wednesday before November 23" day = date(year, 11, 22) while day.weekday() != 2: # 2=Wednesday day -= timedelta(days=1) return day, "Repentance Day" def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_repentance_day(year)) return days @iso_register('DE-ST') class SaxonyAnhalt(Germany): 'Saxony-Anhalt' include_epiphany = True all_time_include_reformation_day = True @iso_register('DE-SH') class SchleswigHolstein(Germany): 'Schleswig-Holstein' include_reformation_day_2018 = True @iso_register('DE-TH') class Thuringia(Germany): 'Thuringia' all_time_include_reformation_day = True calendra-7.9.0/calendra/europe/greece.py000066400000000000000000000014601457013633400201630ustar00rootroot00000000000000from ..core import OrthodoxCalendar from ..registry_tools import iso_register @iso_register('GR') class Greece(OrthodoxCalendar): 'Greece' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (3, 25, "Independence Day"), (10, 28, "Ohi Day"), ) # Christian holidays include_epiphany = True include_clean_monday = True include_annunciation = True include_good_friday = True include_easter_sunday = True include_easter_monday = True include_whit_sunday = True whit_sunday_label = "Pentecost" include_whit_monday = True include_assumption = True include_boxing_day = True boxing_day_label = "Glorifying Mother of God" # No Orthodox Christmas include_orthodox_christmas = False calendra-7.9.0/calendra/europe/guernsey.py000066400000000000000000000030641457013633400205740ustar00rootroot00000000000000from datetime import date from ..core import MON, WesternCalendar from ..registry_tools import iso_register @iso_register('GG') class Guernsey(WesternCalendar): 'Guernsey' include_easter_monday = True include_boxing_day = True shift_new_years_day = True include_good_friday = True def get_spring_bank_holiday(self, year): spring_bank_holiday = Guernsey \ .get_last_weekday_in_month(year, 5, MON) return ( spring_bank_holiday, "Spring Bank Holiday" ) def get_early_may_bank_holiday(self, year): """ Return Early May bank holiday """ # Special case in 2020, for the 75th anniversary of the end of WWII. if year == 2020: return ( date(year, 5, 8), "Early May bank holiday (VE day)" ) return ( Guernsey.get_nth_weekday_in_month(year, 5, MON), "Early May Bank Holiday" ) def get_summer_bank_holiday(self, year): return ( Guernsey.get_last_weekday_in_month(year, 8, MON), "Summer Bank Holiday" ) def get_liberation_day(self, year): return (date(year, 5, 9), "Liberation Day") def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_early_may_bank_holiday(year)) days.append(self.get_spring_bank_holiday(year)) days.append(self.get_summer_bank_holiday(year)) days.append(self.get_liberation_day(year)) return days calendra-7.9.0/calendra/europe/hungary.py000066400000000000000000000016301457013633400204050ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('HU') class Hungary(WesternCalendar): 'Hungary' # Christian holidays include_easter_sunday = True include_easter_monday = True include_whit_sunday = True whit_sunday_label = "Pentecost Sunday" include_whit_monday = True whit_monday_label = "Pentecost Monday" include_boxing_day = True boxing_day_label = "Second Day of Christmas" include_all_saints = True # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (3, 15, "National Day"), (8, 20, "St Stephen's Day"), (10, 23, "National Day"), ) def get_variable_days(self, year): # As of 2017, Good Friday became a holiday self.include_good_friday = (year >= 2017) days = super().get_variable_days(year) return days calendra-7.9.0/calendra/europe/iceland.py000066400000000000000000000024611457013633400203320ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, THU, MON from ..registry_tools import iso_register @iso_register('IS') class Iceland(WesternCalendar): 'Iceland' # Christian holidays include_holy_thursday = True include_good_friday = True include_easter_monday = True include_ascension = True include_whit_monday = True include_christmas_eve = True include_boxing_day = True boxing_day_label = "St Stephen's Day" # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (6, 17, "Icelandic National Day"), (12, 31, "New Year's Eve"), ) def get_first_day_of_summer(self, year): """It's the first thursday *after* April, 18th. If April the 18th is a thursday, then it jumps to the 24th. """ return Iceland.get_nth_weekday_in_month( year, 4, THU, start=date(year, 4, 19)) def get_commerce_day(self, year): return Iceland.get_nth_weekday_in_month(year, 8, MON) def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ (self.get_first_day_of_summer(year), "First day of summer"), (self.get_commerce_day(year), "Commerce Day"), ]) return days calendra-7.9.0/calendra/europe/ireland.py000066400000000000000000000041101457013633400203420ustar00rootroot00000000000000from datetime import date, timedelta from ..core import WesternCalendar, MON from ..registry_tools import iso_register @iso_register('IE') class Ireland(WesternCalendar): 'Ireland' include_easter_monday = True include_boxing_day = True boxing_day_label = "St. Stephen's Day" shift_new_years_day = True def get_june_holiday(self, year): return ( Ireland.get_nth_weekday_in_month(year, 6, MON), "June Holiday" ) def get_august_holiday(self, year): return ( Ireland.get_nth_weekday_in_month(year, 8, MON), "August Holiday" ) def get_variable_days(self, year): self.include_whit_monday = (year <= 1973) days = super().get_variable_days(year) # St Patrick's day st_patrick = date(year, 3, 17) days.append((st_patrick, "Saint Patrick's Day")) if st_patrick.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(st_patrick), "Saint Patrick substitute")) # May Day if year >= 1994: days.append(( Ireland.get_nth_weekday_in_month(year, 5, MON), "May Day" )) days.append(self.get_june_holiday(year)) days.append(self.get_august_holiday(year)) if year >= 1977: days.append(( Ireland.get_last_weekday_in_month(year, 10, MON), "October Holiday" )) # Boxing day & Xmas shift christmas = date(year, 12, 25) st_stephens_day = date(year, 12, 26) if christmas.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(christmas) days.append((shift, "Christmas Shift")) days.append((shift + timedelta(days=1), "St. Stephen's Day Shift")) elif st_stephens_day.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(st_stephens_day) days.append((shift, "St. Stephen's Day Shift")) return days calendra-7.9.0/calendra/europe/italy.py000066400000000000000000000011721457013633400200530ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('IT') class Italy(WesternCalendar): 'Italy' # Civil holidays include_labour_day = True labour_day_label = "International Workers' Day" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (4, 25, "Liberation Day"), (6, 2, "Republic Day"), ) # Christian holidays include_immaculate_conception = True include_epiphany = True include_easter_monday = True include_assumption = True include_all_saints = True include_boxing_day = True boxing_day_label = "St Stephen's Day" calendra-7.9.0/calendra/europe/latvia.py000066400000000000000000000034111457013633400202070ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('LV') class Latvia(WesternCalendar): 'Latvia' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (6, 23, "Midsummer Day"), (6, 24, "St. John's Day"), (12, 31, "New Years Eve"), ) # Christian holidays include_good_friday = True include_easter_sunday = True include_easter_monday = True include_christmas_eve = True include_christmas = True include_boxing_day = True def get_independence_days(self, year): """returns a possibly empty list of (date, holiday_name) tuples""" days = [] if year > 2004: actual_date = date(year, 5, 4) days = [(actual_date, "Restoration of Independence Day")] if actual_date.weekday() in self.get_weekend_days(): days += [(self.find_following_working_day(actual_date), "Restoration of Independence Observed")] return days def get_republic_days(self, year): """returns a possibly empty list of (date, holiday_name) tuples""" days = [] if year > 1918: actual_date = date(year, 11, 18) days = [(actual_date, "Proclamation of Republic Day")] if actual_date.weekday() in self.get_weekend_days(): days += [(self.find_following_working_day(actual_date), "Proclamation of Republic Observed")] return days def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_independence_days(year)) days.extend(self.get_republic_days(year)) return days calendra-7.9.0/calendra/europe/lithuania.py000066400000000000000000000026461457013633400207160ustar00rootroot00000000000000from ..core import WesternCalendar, SUN from ..registry_tools import iso_register @iso_register('LT') class Lithuania(WesternCalendar): 'Lithuania' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 16, "Restoration of the State Day"), (3, 11, "Restoration of Independence Day"), (6, 24, "St. John's Day"), (7, 6, "Anniversary of the Coronation of King Mindaugas"), ) # Christian holidays include_easter_sunday = True include_easter_monday = True include_assumption = True include_all_saints = True include_christmas_eve = True include_christmas = True include_boxing_day = True boxing_day_label = "Second day of Christmas" def get_mothers_day(self, year): return ( Lithuania.get_nth_weekday_in_month(year, 5, SUN, 1), "Mother's day" ) def get_fathers_day(self, year): return ( Lithuania.get_nth_weekday_in_month(year, 6, SUN, 1), "Father's day" ) def get_variable_days(self, year): # All Souls day was introduced as of 2020 # https://en.wikipedia.org/wiki/Public_holidays_in_Lithuania self.include_all_souls = year >= 2020 days = super().get_variable_days(year) days.append(self.get_mothers_day(year)) days.append(self.get_fathers_day(year)) return days calendra-7.9.0/calendra/europe/luxembourg.py000066400000000000000000000013441457013633400211230ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('LU') class Luxembourg(WesternCalendar): 'Luxembourg' # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_all_saints = True include_assumption = True include_boxing_day = True # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (6, 23, "Luxembourg National Holiday"), ) def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if year > 2018: days.append((date(year, 5, 9), "Europe Day")) return days calendra-7.9.0/calendra/europe/malta.py000066400000000000000000000017421457013633400200320ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('MT') class Malta(WesternCalendar): 'Malta' # Christian holidays include_good_friday = True include_assumption = True include_immaculate_conception = True include_christmas = True # Civil holidays include_labour_day = True labour_day_label = "Worker's Day" # (Jum il-Ħaddiem) FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( # National Holidays (3, 31, "Freedom Day"), # (Jum il-Ħelsien) (6, 7, "Sette Giugno"), (9, 8, "Victory Day"), # (Jum il-Vitorja) (9, 21, "Independence Day"), # (Jum l-Indipendenza) (12, 13, "Republic Day"), # (Jum ir-Repubblika) # Public Holidays (2, 10, "Feast of Saint Paul's Shipwreck"), (3, 19, "Feast of Saint Joseph"), # (San Ġużepp) (6, 29, "Feast of Saint Peter & Saint Paul"), # (L-Imnarja) ) calendra-7.9.0/calendra/europe/monaco.py000066400000000000000000000011361457013633400202050ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('MC') class Monaco(WesternCalendar): 'Monaco' # Christian holidays include_easter_monday = True include_ascension = True include_whit_monday = True include_all_saints = True include_assumption = True include_corpus_christi = True include_immaculate_conception = True # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 27, "Saint Dévote's Day"), (11, 19, "H.S.H. the Sovereign Prince's Day"), ) calendra-7.9.0/calendra/europe/netherlands.py000066400000000000000000000215421457013633400212430ustar00rootroot00000000000000from datetime import date, timedelta from ..core import WesternCalendar, SUN, ISO_SAT from ..registry_tools import iso_register @iso_register('NL') class Netherlands(WesternCalendar): 'Netherlands' include_good_friday = True include_easter_sunday = True include_easter_monday = True include_ascension = True include_whit_sunday = True include_whit_monday = True include_boxing_day = True observance_shift = None FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 5, "Liberation Day"), ) def __init__(self, include_carnival=False): self.include_carnival = include_carnival super().__init__() def get_king_queen_day(self, year): """27 April unless this is a Sunday in which case it is the 26th Before 2013 it was called Queensday, falling on 30 April, unless this is a Sunday in which case it is the 29th. """ if year > 2013: king_day = date(year, 4, 27) if king_day.weekday() != SUN: return king_day, "King's day" return king_day - timedelta(days=1), "King's day" else: queen_day = date(year, 4, 30) if queen_day.weekday() != SUN: return queen_day, "Queen's day" return queen_day - timedelta(days=1), "Queen's day" def get_carnival_days(self, year): """Carnival starts 7 weeks before Easter Sunday and lasts 3 days.""" n_days = 3 start = self.get_easter_sunday(year) - timedelta(weeks=7) return [ ( start + timedelta(days=i), "Carnival" ) for i in range(n_days) ] def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_king_queen_day(year)) if self.include_carnival: days.extend(self.get_carnival_days(year)) return days FALL_HOLIDAYS_EARLY_REGIONS = { 2025: ["south"], 2024: ["south"], 2023: ["middle", "south"], 2022: ["north"], 2021: ["north", "middle"], 2020: ["north"], 2019: ["south"], 2018: ["south"], 2017: ["middle", "south"], 2016: ["north", "middle"], } SPRING_HOLIDAYS_EARLY_REGIONS = { 2025: ["north"], 2024: ["south"], 2023: ["south"], 2022: ["north"], 2021: ["south"], 2020: ["north"], 2019: ["north"], 2018: ["south"], 2017: ["north"], 2016: ["middle", "south"], } SUMMER_HOLIDAYS_EARLY_REGIONS = { 2025: ["south"], 2024: ["south"], 2023: ["middle"], 2022: ["middle"], 2021: ["north"], 2020: ["north"], 2019: ["south"], 2018: ["south"], 2017: ["middle"], 2016: ["middle"], } SUMMER_HOLIDAYS_LATE_REGIONS = { 2025: ["middle"], 2024: ["north"], 2023: ["north"], 2022: ["south"], 2021: ["south"], 2020: ["middle"], 2019: ["middle"], 2018: ["north"], 2017: ["north"], 2016: ["south"], } class NetherlandsWithSchoolHolidays(Netherlands): """Netherlands with school holidays (2016 to 2025). Data source and regulating body: https://www.rijksoverheid.nl/onderwerpen/schoolvakanties/overzicht-schoolvakanties-per-schooljaar """ def __init__(self, region, carnival_instead_of_spring=False, **kwargs): """ Set up a calendar incl. school holidays for a specific region :param region: either "north", "middle" or "south" """ if region not in ("north", "middle", "south"): raise ValueError("Set region to 'north', 'middle' or 'south'.") self.region = region self.carnival_instead_of_spring = carnival_instead_of_spring if carnival_instead_of_spring and "include_carnival" not in kwargs: kwargs["include_carnival"] = True super().__init__(**kwargs) def get_fall_holidays(self, year): """ Return Fall holidays. They start at week 43 or 44 and last for 9 days """ if year not in FALL_HOLIDAYS_EARLY_REGIONS: raise NotImplementedError(f"Unknown fall holidays for {year}.") n_days = 9 week = 43 # Exceptional years if year == 2024: week = 44 # Holiday starts on the preceding Saturday start = self.get_iso_week_date(year, week - 1, ISO_SAT) # Some regions have their fall holiday 1 week earlier if self.region in FALL_HOLIDAYS_EARLY_REGIONS[year]: start = start - timedelta(weeks=1) return [ (start + timedelta(days=i), "Fall holiday") for i in range(n_days) ] def get_christmas_holidays(self, year): """ Return Christmas holidays Christmas holidays run partially in December and partially in January (spillover from previous year). """ return ( self._get_christmas_holidays_december(year) + self._get_christmas_holidays_january(year) ) def _get_christmas_holidays_december(self, year): # 27 December is always in a full week of holidays week = date(year, 12, 27).isocalendar()[1] # Holiday starts on the preceding Saturday start = self.get_iso_week_date(year, week - 1, ISO_SAT) return [ (start + timedelta(days=i), "Christmas holiday") for i in range((date(year, 12, 31) - start).days + 1) ] def _get_christmas_holidays_january(self, year): # 27 December is always in a full week of holidays week = date(year - 1, 12, 27).isocalendar()[1] # Holiday ends 15 days after the preceding Saturday # Saturday of the previous week (previous year!) start = self.get_iso_week_date(year - 1, week - 1, ISO_SAT) end = start + timedelta(days=15) return [ (date(year, 1, 1) + timedelta(days=i), "Christmas holiday") for i in range((end - date(year, 1, 1)).days + 1) ] def get_spring_holidays(self, year): """ Return the Spring holidays They start at week 8 or 9 and last for 9 days. """ if year not in SPRING_HOLIDAYS_EARLY_REGIONS: raise NotImplementedError(f"Unknown spring holidays for {year}.") n_days = 9 week = 9 # Exceptional years if year in [2024, 2021]: week = 8 # Holiday starts on the preceding Saturday start = self.get_iso_week_date(year, week - 1, ISO_SAT) # Some regions have their spring holiday 1 week earlier if self.region in SPRING_HOLIDAYS_EARLY_REGIONS[year]: start = start - timedelta(weeks=1) return [ (start + timedelta(days=i), "Spring holiday") for i in range(n_days) ] def get_carnival_holidays(self, year): """ Return Carnival holidays Carnival holidays start 7 weeks and 1 day before Easter Sunday and last 9 days. """ n_days = 9 start = self.get_easter_sunday(year) - timedelta(weeks=7, days=1) return [ (start + timedelta(days=i), "Carnival holiday") for i in range(n_days) ] def get_may_holidays(self, year): """ Return May holidays They start at week 18 (or 17) and last for 18 days """ n_days = 9 week = 18 # Exceptional years if year == 2017: week = 17 # Holiday starts on the preceding Saturday start = self.get_iso_week_date(year, week - 1, ISO_SAT) return [ (start + timedelta(days=i), "May holiday") for i in range(n_days) ] def get_summer_holidays(self, year): """ Return the summer holidays as a list """ if year not in SUMMER_HOLIDAYS_EARLY_REGIONS or \ year not in SUMMER_HOLIDAYS_LATE_REGIONS: raise NotImplementedError(f"Unknown summer holidays for {year}.") n_days = 44 week = 29 # Holiday starts on the preceding Saturday start = self.get_iso_week_date(year, week - 1, ISO_SAT) # Some regions have their summer holiday 1 week earlier if self.region in SUMMER_HOLIDAYS_EARLY_REGIONS[year]: start = start - timedelta(weeks=1) if self.region in SUMMER_HOLIDAYS_LATE_REGIONS[year]: start = start + timedelta(weeks=1) return [ (start + timedelta(days=i), "Summer holiday") for i in range(n_days) ] def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_fall_holidays(year)) days.extend(self.get_christmas_holidays(year)) if self.carnival_instead_of_spring: days.extend(self.get_carnival_holidays(year)) else: days.extend(self.get_spring_holidays(year)) days.extend(self.get_may_holidays(year)) days.extend(self.get_summer_holidays(year)) return days calendra-7.9.0/calendra/europe/norway.py000066400000000000000000000011451457013633400202500ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('NO') class Norway(WesternCalendar): 'Norway' # Christian holidays include_holy_thursday = True include_good_friday = True include_easter_sunday = True include_easter_monday = True include_ascension = True include_whit_monday = True include_whit_sunday = True include_boxing_day = True boxing_day_label = "St Stephen's Day" # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (5, 17, "Constitution Day"), ) calendra-7.9.0/calendra/europe/poland.py000066400000000000000000000012151457013633400202040ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('PL') class Poland(WesternCalendar): 'Poland' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 6, 'Trzech Kroli'), (5, 3, 'Constitution Day'), (11, 11, 'Independence Day'), ) # Christian holidays include_easter_sunday = True include_easter_monday = True include_whit_sunday = True whit_sunday_label = "Pentecost Sunday" include_corpus_christi = True include_assumption = True include_all_saints = True include_boxing_day = True calendra-7.9.0/calendra/europe/portugal.py000066400000000000000000000023531457013633400205700ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('PT') class Portugal(WesternCalendar): 'Portugal' # Christian holidays include_good_friday = True include_easter_sunday = True include_christmas = True include_immaculate_conception = True immaculate_conception_label = "Imaculada Conceição" # Civil holidays include_labour_day = True labour_day_label = "Dia do Trabalhador" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (4, 25, "Dia da Liberdade"), (6, 10, "Dia de Portugal"), (8, 15, "Assunção de Nossa Senhora"), ) def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if year > 2015 or year < 2013: days.append((date(year, 10, 5), "Implantação da República")) days.append((date(year, 11, 1), "Todos os santos")) days.append((date(year, 12, 1), "Restauração da Independência")) return days def get_variable_days(self, year): days = super().get_variable_days(year) if year > 2015 or year < 2013: days.append((self.get_corpus_christi(year), "Corpus Christi")) return days calendra-7.9.0/calendra/europe/romania.py000066400000000000000000000032011457013633400203520ustar00rootroot00000000000000from datetime import date from ..core import OrthodoxCalendar from ..registry_tools import iso_register @iso_register('RO') class Romania(OrthodoxCalendar): 'Romania' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (1, 2, "Day After New Year"), (1, 24, "Union Day"), (8, 15, "Dormition of the Theotokos"), (11, 30, "St. Andrew's Day"), (12, 1, "National Day/Great Union"), ) # Christian holidays include_good_friday = True include_easter_sunday = True include_easter_monday = True include_whit_sunday = True whit_sunday_label = 'Pentecost' include_whit_monday = True include_christmas = True include_boxing_day = True boxing_day_label = 'Christmas Day' # No Orthodox Christmas include_orthodox_christmas = False def get_childrens_day(self, year): """returns a possibly empty list of (date, holiday_name) tuples""" days = [] if year >= 2017: actual_date = date(year, 6, 1) days = [(actual_date, "Children's Day")] return days def get_liberation_day(self, year): """returns a possibly empty list of (date, holiday_name) tuples""" days = [] if 1949 <= year <= 1990: actual_date = date(year, 8, 23) days = [(actual_date, "Liberation from Fascist Occupation Day")] return days def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_childrens_day(year)) days.extend(self.get_liberation_day(year)) return days calendra-7.9.0/calendra/europe/russia.py000066400000000000000000000067331457013633400202470ustar00rootroot00000000000000from datetime import date from ..core import OrthodoxCalendar, MON, daterange, cleaned_date from ..registry_tools import iso_register @iso_register('RU') class Russia(OrthodoxCalendar): 'Russia' # Civil holidays include_labour_day = True FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (1, 2, "Day After New Year"), (2, 23, "Defendence of the Fatherland"), (3, 8, "International Women's Day"), (5, 9, "Victory Day"), (6, 12, "National Day"), (11, 4, "Day of Unity"), ) # Christian holidays include_christmas = False covid19_2020_start = date(2020, 3, 28) covid19_2020_end = date(2020, 4, 30) def get_fixed_holidays(self, year): if year >= 1992: self.labour_day_label = "The Day of Spring and Labour" else: self.labour_day_label = "International Workers' Day" days = super().get_fixed_holidays(year) if year >= 2005: days.extend([ (date(year, 1, 3), "Third Day after New Year"), (date(year, 1, 4), "Fourth Day after New Year"), (date(year, 1, 5), "Fifth Day after New Year"), (date(year, 1, 6), "Sixth Day after New Year"), (date(year, 1, 8), "Eighth Day after New Year"), ]) if year == 2020: index = 1 for day in daterange(self.covid19_2020_start, self.covid19_2020_end): days.append( (day, f"Non-Working Day (COVID-19) #{index}") ) index += 1 # Adding May extra days days.extend([ (date(year, 5, 4), "May 4th, 2020 holiday"), (date(year, 5, 5), "Day of Spring and Labor"), ]) # Extra COVID-19 in May days.extend([ (date(year, 5, 6), "Covid-19 May #1"), (date(year, 5, 7), "Covid-19 May #2"), (date(year, 5, 8), "Covid-19 May #3"), ]) # Constitution Vote Public Holiday days.append((date(year, 7, 1), "Constitution Vote Public Holiday")) elif year == 2021: days.extend([ (date(year, 2, 22), "Day Before Defendence of the Fatherland"), (date(year, 11, 5), 'Day After Day of Unity'), (date(year, 12, 31), "New Year's Eve"), ]) return days def get_calendar_holidays(self, year): holidays = super().get_calendar_holidays(year) shifts = [] for day, label in holidays: if day.month == 1 and day.day in range(1, 9): continue # Add an exception for 2020 non-working days due to COVID-19 if self.covid19_2020_start <= day <= self.covid19_2020_end: continue # pragma: no cover if day.weekday() in self.get_weekend_days(): shifts.append(( self.get_first_weekday_after(day, MON), label + " shift" )) holidays.extend(shifts) return holidays def is_working_day(self, day, extra_working_days=None, extra_holidays=None): day = cleaned_date(day) if day == date(2021, 2, 20): return True return super().is_working_day( day, extra_working_days=extra_working_days, extra_holidays=extra_holidays ) calendra-7.9.0/calendra/europe/scotland/000077500000000000000000000000001457013633400201655ustar00rootroot00000000000000calendra-7.9.0/calendra/europe/scotland/__init__.py000066400000000000000000000332711457013633400223040ustar00rootroot00000000000000""" Scotland specific module. The main source of information is: https://en.wikipedia.org/wiki/Public_and_bank_holidays_in_Scotland Note on "inheritance": * Carnoustie and Monifieth area is a subdivision of Angus * Lanark is part of South Lanarkshire FIXME: * Galashiels is part of the Scottish Borders * Hawick is part of the Scottish Borders * Kilmarnock is probably part of AyrShire (?) * Lanark is part of South Lanarkshire * Linlithgow... part of N/A * Lochaber... part of N/A * ... """ # Since Scotland territories have a lot of different variations, it has become # necessary to split this module and associated tests from datetime import date, timedelta import warnings from ...core import WesternCalendar, MON, THU, FRI from .mixins import ( SpringHolidayFirstMondayApril, SpringHolidaySecondMondayApril, SpringHolidayTuesdayAfterFirstMondayMay, SpringHolidayLastMondayMay, SpringHolidayFirstMondayJune, VictoriaDayFourthMondayMay, VictoriaDayLastMondayMay, VictoriaDayFirstMondayJune, FairHolidayLastMondayJune, FairHolidayFirstMondayJuly, FairHolidaySecondMondayJuly, FairHolidayThirdMondayJuly, FairHolidayLastMondayJuly, FairHolidayFourthFridayJuly, FairHolidayFirstMondayAugust, LateSummer, BattleStirlingBridge, AutumnHolidayLastMondaySeptember, AutumnHolidayFirstMondayOctober, AutumnHolidaySecondMondayOctober, AutumnHolidayThirdMondayOctober, AyrGoldCup, ) class Scotland(WesternCalendar): "Scotland" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 2, "New Year Holiday"), (12, 26, "Boxing Day"), ) include_spring_holiday = False spring_holiday_label = "Spring Holiday" include_fair_holiday = False include_autumn_holiday = False include_saint_andrew = False include_victoria_day = False def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) warnings.warn( """ Please bear in mind that every Scotland (sub)calendar is highly experimental. It appeared throughout out searches that Scottish calendars have many exceptions and somes sources of information contradicts with each other. As a consequence, we advise our user to treat this Scotland submodule with as much care as possible. """ ) def get_may_day(self, year): """ May Day is the first Monday in May """ return ( Scotland.get_nth_weekday_in_month(year, 5, MON), "May Day" ) def get_spring_holiday(self, year): """ Return spring holiday date and label. You need to implement it as soon as the flag `include_spring_holiday` is True. """ raise NotImplementedError( "Tried to add spring holiday while " "`get_spring_holiday` is not implemented.") def get_fair_holiday(self, year): """ Return fair holiday date and label. You need to implement it as soon as the flag `include_fair_holiday` is True. """ raise NotImplementedError( "Tried to add fair holiday while " "`get_fair_holiday` is not implemented.") def get_autumn_holiday(self, year): """ Return autumn holiday date and label. You need to implement it as soon as the flag `include_autumn_holiday` is True. """ raise NotImplementedError( "Tried to add autumn holiday while " "`get_autumn_holiday` is not implemented.") def get_victoria_day(self, year): """ Return Victoria day date and label. You need to implement it as soon as the flag `include_victoria_day` is True. """ raise NotImplementedError( "Tried to add autumn holiday while " "`include_victoria_day` is not implemented.") def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_may_day(year)) if self.include_spring_holiday: # This method is included in the spring_holiday mixins days.append(self.get_spring_holiday(year)) if self.include_fair_holiday: # This method is included in the fair_holiday mixins days.append(self.get_fair_holiday(year)) if self.include_autumn_holiday: # This method is included in the autumn_holiday mixins days.append(self.get_autumn_holiday(year)) if self.include_victoria_day: # This method is included in the victoria_day mixins days.append(self.get_victoria_day(year)) return days def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.include_saint_andrew: days.append((date(year, 11, 30), "Saint Andrew's Day")) return days class Aberdeen( FairHolidaySecondMondayJuly, AutumnHolidayLastMondaySeptember, Scotland): "Aberdeen" include_good_friday = True class Angus( SpringHolidaySecondMondayApril, AutumnHolidayLastMondaySeptember, Scotland): "Angus" include_saint_andrew = True class Arbroath(FairHolidayThirdMondayJuly, Scotland): "Arbroath" class Ayr(SpringHolidayLastMondayMay, AyrGoldCup, Scotland): "Ayr" include_good_friday = True include_easter_monday = True class CarnoustieMonifieth( SpringHolidayFirstMondayApril, AutumnHolidayFirstMondayOctober, Scotland): "Carnoustie & Monifieth" class Clydebank( SpringHolidayTuesdayAfterFirstMondayMay, Scotland): "Clydebank" class DumfriesGalloway(Scotland): "Dumfries & Galloway" include_good_friday = True class Dundee( SpringHolidayFirstMondayApril, VictoriaDayLastMondayMay, FairHolidayLastMondayJuly, AutumnHolidayFirstMondayOctober, Scotland): "Dundee" class EastDunbartonshire( SpringHolidayLastMondayMay, FairHolidayThirdMondayJuly, AutumnHolidayLastMondaySeptember, Scotland): "East Dunbartonshire" include_good_friday = True include_easter_monday = True class Edinburgh(Scotland): "Edinburgh" include_good_friday = True include_easter_monday = True include_spring_holiday = True include_victoria_day = True include_autumn_holiday = True def get_spring_holiday(self, year): """ Return Spring Holiday for Edinburgh. Set to the 3rd Monday of April, unless it falls on Easter Monday, then it's shifted to previous week. """ easter = self.get_easter_monday(year) spring_holiday = self.get_nth_weekday_in_month(year, 4, MON, 3) if easter == spring_holiday: spring_holiday = self.get_nth_weekday_in_month( year, 4, MON, 2) return spring_holiday, self.spring_holiday_label def get_victoria_day(self, year): """ Return Victoria Day for Edinburgh. Set to the Monday strictly before May 24th. It means that if May 24th is a Monday, it's shifted to the week before. """ may_24th = date(year, 5, 24) # Since "MON(day) == 0", it's either the difference between MON and the # current weekday (starting at 0), or 7 days before the May 24th shift = may_24th.weekday() or 7 victoria_day = may_24th - timedelta(days=shift) return victoria_day, "Victoria Day" def get_autumn_holiday(self, year): """ Return Autumn Holiday for Edinburgh. Set to the third Monday in September. Since it's the only region to follow this rule, we won't have a Mixin associated to it. """ return ( self.get_nth_weekday_in_month(year, 9, MON, 3), "Autumn Holiday" ) class Elgin( SpringHolidaySecondMondayApril, FairHolidayLastMondayJune, LateSummer, AutumnHolidayThirdMondayOctober, Scotland): "Elgin" class Falkirk(FairHolidayFirstMondayJuly, BattleStirlingBridge, Scotland): "Falkirk" include_good_friday = True include_easter_monday = True class Fife( VictoriaDayFirstMondayJune, FairHolidayThirdMondayJuly, AutumnHolidayThirdMondayOctober, Scotland): "Fife" include_saint_andrew = True def get_variable_days(self, year): days = super().get_variable_days(year) # Special computation rule, Fife has TWO spring holidays # 1. First Monday in April days.append(( self.get_nth_weekday_in_month(year, 4, MON), "Spring Holiday" )) # 2. First Monday in June days.append(( self.get_nth_weekday_in_month(year, 6, MON), "Spring Holiday" )) return days class Galashiels(SpringHolidayFirstMondayJune, Scotland): "Galashiels" def get_variable_days(self, year): days = super().get_variable_days(year) # Adding Braw Lads Gathering, 1st Friday in July days.append(( self.get_nth_weekday_in_month(year, 7, FRI), "Braw Lads Gathering" )) return days class Glasgow( SpringHolidayLastMondayMay, FairHolidayThirdMondayJuly, AutumnHolidayLastMondaySeptember, Scotland): "Glasgow" include_easter_monday = True class Hawick(Scotland): "Hawick" def get_variable_days(self, year): days = super().get_variable_days(year) # Common Riding happens on the FRI after the first MON in June first_monday = self.get_nth_weekday_in_month(year, 6, MON) friday = first_monday + timedelta(days=4) # And on the saturday. Adding this one, even if SAT is already a # non-working day. saturday = first_monday + timedelta(days=5) days.append((friday, "Common Riding Day 1")) days.append((saturday, "Common Riding Day 2")) return days class Inverclyde(LateSummer, Scotland): "Inverclyde" include_good_friday = True include_easter_monday = True def get_variable_days(self, year): days = super().get_variable_days(year) # Special computation rule, Inverclyde has TWO spring holidays # 1. First Monday in April days.append(( self.get_last_weekday_in_month(year, 4, MON), "Spring Holiday" )) # 2. First Monday in June days.append(( self.get_nth_weekday_in_month(year, 6, MON), "Spring Holiday" )) return days class Inverness( SpringHolidayFirstMondayApril, FairHolidayFirstMondayJuly, AutumnHolidayFirstMondayOctober, Scotland): "Inverness" def get_variable_days(self, year): days = super().get_variable_days(year) days.append(( self.get_nth_weekday_in_month(year, 2, MON), "Winter Holiday (February)" )) days.append(( self.get_nth_weekday_in_month(year, 3, MON), "Winter Holiday (March)" )) days.append(( self.get_nth_weekday_in_month(year, 11, MON), "Samhain Holiday" )) return days class Kilmarnock(AyrGoldCup, Scotland): "Kilmarnock" include_good_friday = True include_easter_monday = True class Lanark(Scotland): "Lanark" def get_variable_days(self, year): days = super().get_variable_days(year) # Lanimer is 2nd THU in June days.append(( self.get_nth_weekday_in_month(year, 6, THU, 2), "Lanimer Day" )) return days class Linlithgow(Scotland): "Linlithgow" def get_variable_days(self, year): days = super().get_variable_days(year) # Linlithgow Marches is on TUE after the 2nd THU in June second_thursday = self.get_nth_weekday_in_month(year, 6, THU, 2) marches_day = second_thursday + timedelta(days=5) days.append(( marches_day, "Linlithgow Marches" )) return days class Lochaber(Scotland): "Lochaber" def get_variable_days(self, year): days = super().get_variable_days(year) # Winter holiday is on the last MON of march days.append(( self.get_last_weekday_in_month(year, 3, MON), "Winter holiday" )) return days class NorthLanarkshire( SpringHolidayLastMondayMay, FairHolidayThirdMondayJuly, AutumnHolidayLastMondaySeptember, Scotland): "North Lanarkshire" include_easter_monday = True class Paisley( VictoriaDayLastMondayMay, FairHolidayFirstMondayAugust, AutumnHolidayLastMondaySeptember, Scotland): "Paisley" include_good_friday = True include_easter_monday = True class Perth( SpringHolidayFirstMondayApril, VictoriaDayFourthMondayMay, BattleStirlingBridge, AutumnHolidayFirstMondayOctober, Scotland): "Perth" class ScottishBorders( SpringHolidayFirstMondayApril, FairHolidayFourthFridayJuly, AutumnHolidaySecondMondayOctober, Scotland): "Scottish Borders" include_saint_andrew = True class SouthLanarkshire( SpringHolidayLastMondayMay, FairHolidayThirdMondayJuly, AutumnHolidayLastMondaySeptember, Scotland): "South Lanarkshire" include_good_friday = True include_easter_monday = True class Stirling( SpringHolidayTuesdayAfterFirstMondayMay, BattleStirlingBridge, Scotland): "Stirling" include_good_friday = True include_easter_monday = True class WestDunbartonshire( AutumnHolidayLastMondaySeptember, Scotland): "West Dunbartonshire" include_good_friday = True include_easter_monday = True calendra-7.9.0/calendra/europe/scotland/mixins/000077500000000000000000000000001457013633400214745ustar00rootroot00000000000000calendra-7.9.0/calendra/europe/scotland/mixins/__init__.py000066400000000000000000000054441457013633400236140ustar00rootroot00000000000000""" Scotland calendar mixins. There are so many of them that it became necessary to move them to a different module. """ from ....core import MON, FRI from datetime import timedelta from .spring_holiday import ( SpringHolidayFirstMondayApril, SpringHolidaySecondMondayApril, SpringHolidayTuesdayAfterFirstMondayMay, SpringHolidayLastMondayMay, SpringHolidayFirstMondayJune, ) from .fair_holiday import ( FairHolidayLastMondayJune, FairHolidayFirstMondayJuly, FairHolidaySecondMondayJuly, FairHolidayThirdMondayJuly, FairHolidayLastMondayJuly, FairHolidayFourthFridayJuly, FairHolidayFirstMondayAugust, ) from .victoria_day import ( VictoriaDayFourthMondayMay, VictoriaDayLastMondayMay, VictoriaDayFirstMondayJune, ) from .autumn_holiday import ( AutumnHolidayLastMondaySeptember, AutumnHolidayFirstMondayOctober, AutumnHolidaySecondMondayOctober, AutumnHolidayThirdMondayOctober, ) class LateSummer: def get_variable_days(self, year): """ Add Late Summer holiday (First Monday of September) """ days = super().get_variable_days(year) days.append(( self.get_nth_weekday_in_month(year, 9, MON), "Late Summer Holiday" )) return days class BattleStirlingBridge: def get_variable_days(self, year): """ Add Battle of Stirling Bridge holiday (Second Monday of September) """ days = super().get_variable_days(year) days.append(( self.get_nth_weekday_in_month(year, 9, MON, 2), "Battle of Stirling Bridge Holiday" )) return days class AyrGoldCup: def get_variable_days(self, year): days = super().get_variable_days(year) # Ayr Gold Cup gold_cup_friday = self.get_nth_weekday_in_month(year, 9, FRI, 3) days.append( (gold_cup_friday, "Ayr Gold Cup Friday") ) days.append( (gold_cup_friday + timedelta(days=3), "Ayr Gold Cup Monday") ) return days __all__ = [ 'AyrGoldCup', 'SpringHolidayFirstMondayApril', 'SpringHolidaySecondMondayApril', 'SpringHolidayTuesdayAfterFirstMondayMay', 'SpringHolidayLastMondayMay', 'SpringHolidayFirstMondayJune', 'VictoriaDayFourthMondayMay', 'VictoriaDayLastMondayMay', 'VictoriaDayTuesdayAfterFirstMondayMay', 'VictoriaDayFirstMondayJune', 'FairHolidayLastMondayJune', 'FairHolidayFirstMondayJuly', 'FairHolidaySecondMondayJuly', 'FairHolidayThirdMondayJuly', 'FairHolidayLastMondayJuly', 'FairHolidayFourthFridayJuly', 'FairHolidayFirstMondayAugust', 'AutumnHolidayLastMondaySeptember', 'AutumnHolidayFirstMondayOctober', 'AutumnHolidaySecondMondayOctober', 'AutumnHolidayThirdMondayOctober', ] calendra-7.9.0/calendra/europe/scotland/mixins/autumn_holiday.py000066400000000000000000000020131457013633400250640ustar00rootroot00000000000000""" Autumn Holiday mixins """ from ....core import MON class AutumHoliday: include_autumn_holiday = True autumn_holiday_label = "Autumn Holiday" class AutumnHolidayLastMondaySeptember(AutumHoliday): def get_autumn_holiday(self, year): return ( self.get_last_weekday_in_month(year, 9, MON), self.autumn_holiday_label ) class AutumnHolidayFirstMondayOctober(AutumHoliday): def get_autumn_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 10, MON), self.autumn_holiday_label ) class AutumnHolidaySecondMondayOctober(AutumHoliday): def get_autumn_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 10, MON, 2), self.autumn_holiday_label ) class AutumnHolidayThirdMondayOctober(AutumHoliday): def get_autumn_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 10, MON, 3), self.autumn_holiday_label ) calendra-7.9.0/calendra/europe/scotland/mixins/fair_holiday.py000066400000000000000000000031241457013633400245000ustar00rootroot00000000000000""" Fair Holiday mixins """ from ....core import MON, FRI class FairHoliday: include_fair_holiday = True fair_holiday_label = "Fair Holiday" class FairHolidayLastMondayJune(FairHoliday): def get_fair_holiday(self, year): return ( self.get_last_weekday_in_month(year, 6, MON), self.fair_holiday_label ) class FairHolidayFirstMondayJuly(FairHoliday): def get_fair_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 7, MON), self.fair_holiday_label ) class FairHolidaySecondMondayJuly(FairHoliday): def get_fair_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 7, MON, 2), self.fair_holiday_label ) class FairHolidayThirdMondayJuly(FairHoliday): def get_fair_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 7, MON, 3), self.fair_holiday_label ) class FairHolidayLastMondayJuly(FairHoliday): def get_fair_holiday(self, year): return ( self.get_last_weekday_in_month(year, 7, MON), self.fair_holiday_label ) class FairHolidayFourthFridayJuly(FairHoliday): def get_fair_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 7, FRI, 4), self.fair_holiday_label ) class FairHolidayFirstMondayAugust(FairHoliday): def get_fair_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 8, MON), self.fair_holiday_label ) calendra-7.9.0/calendra/europe/scotland/mixins/spring_holiday.py000066400000000000000000000024141457013633400250620ustar00rootroot00000000000000""" Spring Holiday mixins """ from datetime import timedelta from ....core import MON class SpringHoliday: include_spring_holiday = True class SpringHolidayFirstMondayApril(SpringHoliday): def get_spring_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 4, MON), self.spring_holiday_label ) class SpringHolidaySecondMondayApril(SpringHoliday): def get_spring_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 4, MON, 2), self.spring_holiday_label ) class SpringHolidayTuesdayAfterFirstMondayMay(SpringHoliday): def get_spring_holiday(self, year): first_monday = self.get_nth_weekday_in_month(year, 5, MON) return ( first_monday + timedelta(days=1), self.spring_holiday_label ) class SpringHolidayLastMondayMay(SpringHoliday): def get_spring_holiday(self, year): return ( self.get_last_weekday_in_month(year, 5, MON), self.spring_holiday_label ) class SpringHolidayFirstMondayJune(SpringHoliday): def get_spring_holiday(self, year): return ( self.get_nth_weekday_in_month(year, 6, MON), self.spring_holiday_label ) calendra-7.9.0/calendra/europe/scotland/mixins/victoria_day.py000066400000000000000000000014301457013633400245210ustar00rootroot00000000000000""" Victoria Day mixins """ from ....core import MON class VictoriaDayMixin: include_victoria_day = True victoria_day_label = "Victoria Day" class VictoriaDayFourthMondayMay(VictoriaDayMixin): def get_victoria_day(self, year): return ( self.get_nth_weekday_in_month(year, 5, MON, 4), self.victoria_day_label ) class VictoriaDayLastMondayMay(VictoriaDayMixin): def get_victoria_day(self, year): return ( self.get_last_weekday_in_month(year, 5, MON), self.victoria_day_label ) class VictoriaDayFirstMondayJune(VictoriaDayMixin): def get_victoria_day(self, year): return ( self.get_nth_weekday_in_month(year, 6, MON), self.victoria_day_label ) calendra-7.9.0/calendra/europe/serbia.py000066400000000000000000000011211457013633400201700ustar00rootroot00000000000000from ..core import OrthodoxCalendar from ..registry_tools import iso_register @iso_register('RS') class Serbia(OrthodoxCalendar): 'Serbia' FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (1, 2, "Day After New Year"), (2, 15, "Statehood Day"), (2, 16, "Statehood Day"), (5, 2, "Labour Day Holiday"), (11, 11, "Armistice Day"), ) # Civil holidays include_labour_day = True # Christian holidays include_good_friday = True include_easter_sunday = True include_easter_monday = True include_christmas = False calendra-7.9.0/calendra/europe/slovakia.py000066400000000000000000000016651457013633400205510ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('SK') class Slovakia(WesternCalendar): 'Slovakia' # Christian holidays include_epiphany = True include_easter_monday = True include_good_friday = True include_all_saints = True include_christmas_eve = True include_boxing_day = True boxing_day_label = "St. Stephen's Day (The Second Christmas Day)" # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 1, "Day of the Establishment of the Slovak Republic"), (5, 8, "Liberation Day"), (7, 5, "Saints Cyril and Methodius Day"), (8, 29, "Slovak National Uprising anniversary"), (9, 1, "Day of the Constitution of the Slovak Republic"), (9, 15, "Day of Blessed Virgin Mary, patron saint of Slovakia"), (11, 17, "Struggle for Freedom and Democracy Day"), ) calendra-7.9.0/calendra/europe/slovenia.py000066400000000000000000000025001457013633400205450ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('SI') class Slovenia(WesternCalendar): 'Slovenia' # Christian holidays include_easter_sunday = True include_easter_monday = True include_whit_sunday = True include_assumption = True include_christmas = True # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (2, 8, "Preseren Day, the Slovenian Cultural Holiday"), (4, 27, "Day of Uprising Against Occupation"), (5, 2, "Labour Day"), # In Slovenia, Labour Day is 2-day long. (6, 25, "Statehood Day"), (10, 31, "Reformation Day"), (11, 1, "Day of Remembrance of the Dead"), (12, 26, "Independence and Unity Day"), ) def get_variable_days(self, year): days = super().get_variable_days(year) # From 1955 until May 2012, when the National Assembly of Slovenia # passed the Public Finance Balance Act, 2 January was a work-free day. # It has been re-introduced in 2017. # Source - Wikipedia # https://en.wikipedia.org/wiki/Public_holidays_in_Slovenia if 1955 <= year <= 2012 or year >= 2017: days.append((date(year, 1, 2), "January 2nd")) return days calendra-7.9.0/calendra/europe/spain.py000066400000000000000000000120221457013633400200370ustar00rootroot00000000000000from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('ES') class Spain(WesternCalendar): 'Spain' # Christian holidays include_epiphany = True include_good_friday = True include_assumption = True include_all_saints = True include_immaculate_conception = True # Civil holidays include_labour_day = True labour_day_label = "Día del trabajador" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (10, 12, "Fiesta nacional de España"), (12, 6, "Día de la Constitución Española") ) @iso_register('ES-AN') class Andalusia(Spain): "Andalusia" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (2, 28, "Andalusian National Day"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-AR') class Aragon(Spain): "Aragon" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (4, 23, "Aragonese National Day"), (12, 20, "Aragon Ombudsman Day"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-CL') class CastileAndLeon(Spain): "Castile and León" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (4, 23, "Día de Castilla y León"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-CM') class CastillaLaMancha(Spain): "Castilla-La Mancha" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (5, 31, "Día de la Región Castilla-La Mancha"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-CN') class CanaryIslands(Spain): "Canary Islands" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (5, 30, "Día de Canarias"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-CT') class Catalonia(Spain): "Catalonia" include_easter_monday = True include_boxing_day = True boxing_day_label = "Sant Esteve" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (9, 11, "Diada nacional de Catalunya"), (6, 24, "La revetlla de Sant Joan, Nit de Sant Joan"), ) @iso_register('ES-EX') class Extremadura(Spain): "Extremadura" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (9, 8, "Día de Extremadura"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-GA') class Galicia(Spain): "Galicia" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (5, 17, "Día das Letras Galegas"), (7, 25, "Santiago Apóstol o Día da Patria Galega"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-IB') class BalearicIslands(Spain): "Balearic Islands" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (3, 1, "Dia de les Illes Balears"), ) # Christian holidays include_holy_thursday = True # Also called Maundy thursday include_easter_monday = True @iso_register('ES-RI') class LaRioja(Spain): "La Rioja" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (6, 9, "Dia de La Rioja"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-MD') class CommunityofMadrid(Spain): "Community of Madrid" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (5, 2, "Fiesta de la Comunidad de Madrid"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-MC') class Murcia(Spain): "Region of Murcia" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (6, 9, "Día de la Región de Murcia"), (3, 19, "San José"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-NA') class Navarre(Spain): "Navarre" # Christian holidays include_holy_thursday = True # Also called Maundy thursday include_easter_monday = True @iso_register('ES-AS') class Asturias(Spain): "Asturias" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (9, 8, "Día de Asturias"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-PV') class BasqueCountry(Spain): "Basque Country" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (10, 25, "Euskadi Eguna"), ) # Christian holidays include_holy_thursday = True # Also called Maundy thursday include_easter_monday = True @iso_register('ES-CB') class Cantabria(Spain): "Cantabria" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (9, 15, "Día de Cantabria o Día de La Montaña"), ) # Christian holiday include_holy_thursday = True # Also called Maundy thursday @iso_register('ES-VC') class ValencianCommunity(Spain): "Valencian Community" FIXED_HOLIDAYS = Spain.FIXED_HOLIDAYS + ( (3, 19, "San José"), (10, 9, "Dia de la Comunitat Valenciana"), ) # Christian holiday include_easter_monday = True calendra-7.9.0/calendra/europe/sweden.py000066400000000000000000000034551457013633400202240ustar00rootroot00000000000000from datetime import date from ..core import WesternCalendar, FRI, SAT from ..registry_tools import iso_register @iso_register('SE') class Sweden(WesternCalendar): 'Sweden' # Christian holidays include_epiphany = True include_good_friday = True include_easter_sunday = True include_easter_monday = True include_ascension = True include_whit_sunday = True whit_sunday_label = "Pentecost" # Christmas Eve is not a holiday but not a work day either include_christmas_eve = True include_boxing_day = True boxing_day_label = "Second Day of Christmas" observance_shift = None # Civil holidays include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (6, 6, "National Day"), # New Year's Eve is not a holiday but not a work day either (12, 31, "New Year's Eve") ) # Midsummer Eve is not a holiday but not a work day either def get_midsummer_eve(self, year): date_eve = Sweden.get_nth_weekday_in_month( year, 6, FRI, start=date(year, 6, 19)) return date_eve def get_midsummer_day(self, year): date_eve = Sweden.get_nth_weekday_in_month( year, 6, SAT, start=date(year, 6, 20)) return date_eve def get_variable_all_saints(self, year): all_saints = date(year, 10, 31) if all_saints.weekday() != SAT: all_saints = Sweden.get_nth_weekday_in_month( year, 11, SAT) return all_saints def get_variable_days(self, year): days = super().get_variable_days(year) days.append((self.get_midsummer_day(year), "Midsummer's Day")) days.append((self.get_midsummer_eve(year), "Midsummer's Eve")) days.append((self.get_variable_all_saints(year), "All Saints")) return days calendra-7.9.0/calendra/europe/switzerland.py000066400000000000000000000210251457013633400212760ustar00rootroot00000000000000from datetime import date, timedelta from ..core import WesternCalendar, SUN from ..registry_tools import iso_register @iso_register('CH') class Switzerland(WesternCalendar): 'Switzerland' # ChristianMixin entries common to (most) cantons - opt out include_good_friday = True # not in TI, VS include_easter_sunday = True include_easter_monday = True # not in VS include_ascension = True include_whit_sunday = True include_whit_monday = True # not in VS include_christmas = True include_boxing_day = True # not in GE, NE, VS, VD # ChristianMixin entries with varying observance - opt in include_epiphany = False include_corpus_christi = False include_assumption = False include_all_saints = False include_immaculate_conception = False # Swiss entries with varying observance - opt in include_berchtolds_day = False include_st_josephs_day = False FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (8, 1, "National Holiday"), ) def has_berchtolds_day(self, year): return self.include_berchtolds_day def get_federal_thanksgiving_monday(self, year): "Monday following the 3rd sunday of September" third_sunday = self.get_nth_weekday_in_month(year, 9, SUN, 3) return ( third_sunday + timedelta(days=1), "Federal Thanksgiving Monday" ) def get_variable_days(self, year): days = super().get_variable_days(year) if self.has_berchtolds_day(year): days.append((date(year, 1, 2), "Berchtold's Day")) if self.include_st_josephs_day: days.append((date(year, 3, 19), "St Joseph's Day")) return days @iso_register('CH-AG') class Aargau(Switzerland): 'Aargau' include_berchtolds_day = True include_corpus_christi = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-AI') class AppenzellInnerrhoden(Switzerland): 'Appenzell Innerrhoden' include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-AR') class AppenzellAusserrhoden(Switzerland): 'Appenzell Ausserrhoden' include_labour_day = True @iso_register('CH-BE') class Bern(Switzerland): 'Bern' include_berchtolds_day = True @iso_register('CH-BL') class BaselLandschaft(Switzerland): 'Basel-Landschaft' include_labour_day = True @iso_register('CH-BS') class BaselStadt(Switzerland): 'Basel-Stadt' include_labour_day = True @iso_register('CH-FR') class Fribourg(Switzerland): 'Fribourg' include_berchtolds_day = True include_labour_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-GE') class Geneva(Switzerland): 'Geneva' include_boxing_day = False FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (12, 31, "Creation of Geneva Republic"), ) def get_genevan_fast(self, year): "Thursday following the first Sunday of September" first_sunday = self.get_nth_weekday_in_month(year, 9, SUN) # The following thursday is 4 days after return ( first_sunday + timedelta(days=4), "Genevan Fast" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_genevan_fast(year)) return days @iso_register('CH-GL') class Glarus(Switzerland): 'Glarus (Glaris)' include_berchtolds_day = True include_all_saints = True FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (4, 3, "Näfels Ride"), ) @iso_register('CH-GR') class Graubunden(Switzerland): 'Graubünden (Grisons)' include_epiphany = True include_st_josephs_day = True include_corpus_christi = True include_immaculate_conception = True @iso_register('CH-JU') class Jura(Switzerland): 'Jura' include_berchtolds_day = True include_labour_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_boxing_day = False FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (6, 23, "Independence Day"), ) @iso_register('CH-LU') class Luzern(Switzerland): 'Luzern' include_berchtolds_day = True include_epiphany = True include_st_josephs_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-NE') class Neuchatel(Switzerland): 'Neuchâtel' include_boxing_day = False # Conditionally added in get_variable_days(). include_labour_day = True FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (3, 1, "Republic Day"), ) def has_berchtolds_day(self, year): # See https://rsn.ne.ch/DATA/program/books/rsne/pdf/94102.pdf, Art. 3 if date(year, 1, 1).weekday() == SUN: return True return False def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_federal_thanksgiving_monday(year)) # See https://rsn.ne.ch/DATA/program/books/rsne/pdf/94102.pdf, Art. 3 if date(year, 12, 25).weekday() == SUN: days.append((date(year, 12, 26), self.boxing_day_label)) return days @iso_register('CH-NW') class Nidwalden(Switzerland): 'Nidwalden' include_st_josephs_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-OW') class Obwalden(Switzerland): 'Obwalden' include_berchtolds_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (9, 25, "Saint Nicholas of Flüe Day"), ) @iso_register('CH-SG') class StGallen(Switzerland): 'St. Gallen' include_all_saints = True @iso_register('CH-SH') class Schaffhausen(Switzerland): 'Schaffhausen' include_berchtolds_day = True include_labour_day = True @iso_register('CH-SO') class Solothurn(Switzerland): 'Solothurn' include_berchtolds_day = True include_st_josephs_day = True include_labour_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-SZ') class Schwyz(Switzerland): 'Schwyz' include_epiphany = True include_st_josephs_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-TG') class Thurgau(Switzerland): 'Thurgau' include_berchtolds_day = True include_labour_day = True @iso_register('CH-TI') class Ticino(Switzerland): 'Ticino' include_good_friday = False include_epiphany = True include_st_josephs_day = True include_labour_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True FIXED_HOLIDAYS = Switzerland.FIXED_HOLIDAYS + ( (6, 29, "Saints Peter and Paul"), ) @iso_register('CH-UR') class Uri(Switzerland): 'Uri' include_epiphany = True include_st_josephs_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-VD') class Vaud(Switzerland): 'Vaud' include_berchtolds_day = True include_boxing_day = False def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_federal_thanksgiving_monday(year)) return days @iso_register('CH-VS') class Valais(Switzerland): 'Valais' include_good_friday = False include_easter_monday = False include_whit_monday = False include_st_josephs_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True include_boxing_day = False @iso_register('CH-ZG') class Zug(Switzerland): 'Zug' include_berchtolds_day = True include_corpus_christi = True include_assumption = True include_all_saints = True include_immaculate_conception = True @iso_register('CH-ZH') class Zurich(Switzerland): 'Zürich' include_berchtolds_day = True include_labour_day = True calendra-7.9.0/calendra/europe/turkey.py000066400000000000000000000020731457013633400202550ustar00rootroot00000000000000from datetime import timedelta from ..core import IslamicCalendar, SAT, SUN from ..registry_tools import iso_register @iso_register('TR') class Turkey(IslamicCalendar): 'Turkey' include_new_years_day = True shift_new_years_day = False # Even though they're using an islamic calendar, the work week is MON->FRI WEEKEND_DAYS = (SAT, SUN) # Islamic Holidays include_eid_al_fitr = True length_eid_al_fitr = 3 include_eid_al_adha = True length_eid_al_adha = 4 # Civil holidays include_labour_day = True labour_day_label = "Labor and Solidarity Day" FIXED_HOLIDAYS = IslamicCalendar.FIXED_HOLIDAYS + ( (4, 23, "National Sovereignty and Children's Day"), (5, 19, "Commemoration of Atatürk, Youth and Sports Day"), (7, 15, "Democracy and National Unity Day"), (8, 30, "Victory Day"), (10, 29, "Republic Day"), ) def get_delta_islamic_holidays(self, year): """ Turkey Islamic holidays are shifted by one day every year. """ return timedelta(days=-1) calendra-7.9.0/calendra/europe/ukraine.py000066400000000000000000000053741457013633400203770ustar00rootroot00000000000000from datetime import date from ..core import OrthodoxCalendar from ..registry_tools import iso_register @iso_register('UA') class Ukraine(OrthodoxCalendar): 'Ukraine' shift_sunday_holidays = True shift_new_years_day = True FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + ( (3, 8, "International Women’s Day"), (5, 9, "Victory Day"), ) # Civil holidays include_labour_day = True labour_day_label = "Workers Solidarity Day" # Christian holidays include_christmas = False include_good_friday = True include_easter_sunday = True include_easter_monday = True include_whit_monday = True def get_variable_days(self, year): days = super().get_variable_days(year) # Orthodox Christmas holiday is moved when it falls over the week orthodox_christmas = date(year, 1, 7) if orthodox_christmas.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(orthodox_christmas), "Orthodox Christmas (postponed)")) else: days.append((orthodox_christmas, "Orthodox Christmas")) # Constitution Day was celebrated for the first time in 1996 if year >= 1996: constitution_day = date(year, 6, 28) if constitution_day.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(constitution_day), "Constitution Day (postponed)")) else: days.append((constitution_day, "Constitution Day")) # Independence Day was first celebrated in 1991 on the 16th of June # After the official independence has been moved to the 24th of August if year == 1991: days.append((date(year, 6, 16), "Independence Day")) if year >= 1992: independence_day = date(year, 8, 24) if independence_day.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(independence_day), "Independence Day (postponed)")) else: days.append((independence_day, "Independence Day")) # Defender of Ukraine from 2015 # https://en.wikipedia.org/wiki/Defender_of_Ukraine_Day if year >= 2015: days.append((date(year, 10, 14), "Day of Defender of Ukraine")) # Catholic Christmas has become an holiday only starting from 2017 if year >= 2017: days.append((date(year, 12, 25), "Christmas Day")) # Workers Solidarity Day was celebrated also on the 2nd till 2017 if year <= 2017: days.append((date(year, 5, 2), "Workers Solidarity Day")) return days calendra-7.9.0/calendra/europe/united_kingdom.py000066400000000000000000000072651457013633400217420ustar00rootroot00000000000000from datetime import date from dateutil import relativedelta as rd from ..core import Holiday from ..core import WesternCalendar from ..registry_tools import iso_register @iso_register('GB') class UnitedKingdom(WesternCalendar): 'United Kingdom' include_good_friday = True include_easter_sunday = True include_easter_monday = True include_boxing_day = True shift_new_years_day = True non_computable_holiday_dict = { 1973: [(date(1973, 11, 14), "Royal wedding"), ], 1977: [(date(1977, 6, 7), "Queen’s Silver Jubilee"), ], 1981: [(date(1981, 7, 29), "Royal wedding"), ], 1999: [(date(1999, 12, 31), "New Year's Eve"), ], 2002: [(date(2002, 6, 3), "Queen’s Golden Jubilee"), ], 2011: [(date(2011, 4, 29), "Royal Wedding"), ], 2012: [(date(2012, 6, 5), "Queen’s Diamond Jubilee"), ], 2022: [(date(2022, 6, 3), "Queen’s Platinum Jubilee bank holiday"), (date(2022, 9, 19), "State Funeral of Queen Elizabeth II"), ], 2023: [ (date(2023, 5, 8), "Coronation of His Majesty King Charles III"), ], } def get_early_may_bank_holiday(self, year): """ Return Early May bank holiday """ day = date(year, 5, 1) + rd.relativedelta(weekday=rd.MO(1)) desc = "Early May Bank Holiday" indication = "1st Monday in May" # Special case in 2020, for the 75th anniversary of the end of WWII. if year == 2020: day = date(year, 5, 8) desc += " (VE day)" indication = "VE day" return Holiday(day, desc, indication=indication) def get_spring_bank_holiday(self, year): day = date(year, 5, 30) + rd.relativedelta(weekday=rd.MO(-1)) if year in (2012, 2002): day = date(year, 6, 4) if year in (1977,): day = date(year, 6, 6) if year == 2022: day = date(year, 6, 2) return Holiday( day, "Spring Bank Holiday", indication="Last Monday in May", ), def get_late_summer_bank_holiday(self, year): return Holiday( date(year, 8, 31) + rd.relativedelta(weekday=rd.MO(-1)), "Late Summer Bank Holiday", indication="Last Monday in August", ) def non_computable_holiday(self, year): non_computable = self.non_computable_holiday_dict.get(year, None) return non_computable def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_early_may_bank_holiday(year)) days.append(self.get_spring_bank_holiday(year)) days.append(self.get_late_summer_bank_holiday(year)) non_computable = self.non_computable_holiday(year) if non_computable: days.extend(non_computable) return days @iso_register('GB-NIR') class UnitedKingdomNorthernIreland(UnitedKingdom): 'Northern Ireland' def get_variable_days(self, year): days = super().get_variable_days(year) # St Patrick's day st_patrick = date(year, 3, 17) days.append((st_patrick, "Saint Patrick's Day")) if st_patrick.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(st_patrick), "Saint Patrick substitute")) # Battle of boyne battle_of_boyne = date(year, 7, 12) days.append((battle_of_boyne, "Battle of the Boyne")) if battle_of_boyne.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(battle_of_boyne), "Battle of the Boyne substitute")) return days calendra-7.9.0/calendra/exceptions.py000066400000000000000000000013311457013633400176100ustar00rootroot00000000000000""" Core Workalendar Exceptions """ class CalendarError(Exception): """ Base Calendar Error """ class UnsupportedDateType(CalendarError): """ Raised when trying to use an unsupported date/datetime type. """ class ISORegistryError(CalendarError): """ Raised when you are trying to register a non-Calendar object """ class ICalExportError(CalendarError): """ Raised when the iCal export is impossible """ class ICalExportRangeError(ICalExportError): """ Raised when the iCal export is impossible due to wrong range """ class ICalExportTargetPathError(ICalExportError): """ Raised when the iCal export is impossible due to unusable target path """ calendra-7.9.0/calendra/holiday.py000066400000000000000000000114751457013633400170720ustar00rootroot00000000000000import itertools import functools from datetime import date, timedelta from more_itertools import recipes from dateutil import relativedelta as rd class Holiday(date): """ A named holiday with an indicated date, name, and additional keyword attributes. >>> nyd = Holiday(date(2014, 1, 1), "New year") But if New Year's Eve is also a holiday, and it too falls on a weekend, many calendars will have that holiday fall back to the previous friday: >>> from dateutil import relativedelta as rd >>> nye = Holiday(date(2014, 12, 31), "New year's eve", ... observance_shift=dict(weekday=rd.FR(-1))) For compatibility, a Holiday may be treated like a tuple of (date, label) >>> nyd[0] == date(2014, 1, 1) True >>> nyd[1] 'New year' >>> d, label = nyd """ def __new__(cls, date, *args, **kwargs): return super().__new__( cls, date.year, date.month, date.day) def __init__(self, date, name='Holiday', **kwargs): self.name = name vars(self).update(kwargs) def __getitem__(self, n): """ for compatibility as a two-tuple """ tp = self, self.name return tp[n] def __iter__(self): """ for compatibility as a two-tuple """ tp = self, self.name return iter(tp) def replace(self, *args, **kwargs): replaced = super().replace(*args, **kwargs) vars(replaced).update(vars(self)) return replaced def __add__(self, other): orig = date(self.year, self.month, self.day) return Holiday(orig + other, **vars(self)) def __sub__(self, other): orig = date(self.year, self.month, self.day) return Holiday(orig - other, **vars(self)) def nearest_weekday(self, calendar): """ Return the nearest weekday to self. """ weekend_days = calendar.get_weekend_days() deltas = (timedelta(n) for n in itertools.count()) candidates = recipes.flatten( (self - delta, self + delta) for delta in deltas ) matches = ( day for day in candidates if day.weekday() not in weekend_days ) return next(matches) @classmethod def _from_fixed_definition(cls, item): """For backward compatibility, load Holiday object from an item of FIXED_HOLIDAYS class property, which might be just a tuple of month, day, label. """ if isinstance(item, tuple): month, day, label = item any_year = 2000 item = Holiday(date(any_year, month, day), label) return item @classmethod def _from_resolved_definition(cls, item, **kwargs): """For backward compatibility, load Holiday object from a two-tuple or existing Holiday instance. """ if isinstance(item, tuple): item = Holiday(*item, **kwargs) return item @functools.lru_cache() def get_observed_date(self, calendar): """ The date the holiday is observed for the calendar. If the holiday occurs on a weekend, it may be observed on another day as indicated by the observance_shift. The holiday may also specify an 'observe_after' such that it is always shifted after a preceding holiday. For example, Boxing day is always observed after Christmas Day is observed. """ # observance_shift may be overridden in the holiday itself shift = getattr(self, 'observance_shift', calendar.observance_shift) if callable(shift): shifted = shift(self, calendar) else: shift = shift or {} delta = rd.relativedelta(**shift) try: weekend_days = calendar.get_weekend_days() except NotImplementedError: weekend_days = () should_shift = self.weekday() in weekend_days shifted = self + delta if should_shift else self precedent = getattr(self, 'observe_after', None) while precedent and shifted <= precedent.get_observed_date(calendar): shifted += timedelta(days=1) return shifted class SeriesShiftMixin: """ "Series" holidays like the two Islamic Eid's or Chinese Spring Festival span multiple days. If one of these days encounters a non-zero observance_shift, apply that shift to all subsequent members of the series. """ def get_calendar_holidays(self, year): """ Ensure that all events are observed in the order indicated. """ days = super().get_calendar_holidays(year) holidays = sorted(map(Holiday._from_resolved_definition, days)) from more_itertools import pairwise for a, b in pairwise(holidays): b.observe_after = a return holidays calendra-7.9.0/calendra/oceania/000077500000000000000000000000001457013633400164565ustar00rootroot00000000000000calendra-7.9.0/calendra/oceania/__init__.py000066400000000000000000000011461457013633400205710ustar00rootroot00000000000000from .australia import ( Australia, AustralianCapitalTerritory, NewSouthWales, NorthernTerritory, Queensland, SouthAustralia, Tasmania, Hobart, Victoria, WesternAustralia ) from .marshall_islands import MarshallIslands from .new_zealand import NewZealand __all__ = ( # Australia and al. 'Australia', 'AustralianCapitalTerritory', 'NewSouthWales', 'NorthernTerritory', 'Queensland', 'SouthAustralia', 'Tasmania', 'Hobart', 'Victoria', 'WesternAustralia', # Other oceanian countries 'MarshallIslands', 'NewZealand', ) calendra-7.9.0/calendra/oceania/australia.py000066400000000000000000000252651457013633400210270ustar00rootroot00000000000000from datetime import date, timedelta from ..core import WesternCalendar, MON, TUE, SAT, SUN from ..registry_tools import iso_register @iso_register('AU') class Australia(WesternCalendar): "Australia" include_good_friday = True include_easter_monday = True include_queens_birthday = False include_labour_day_october = False include_boxing_day = True # Shall we shift Anzac Day? shift_anzac_day = True ANZAC_SHIFT_DAYS = (SAT, SUN) FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (1, 26, "Australia Day"), ) def get_canberra_day(self, year): return ( Australia.get_nth_weekday_in_month(year, 3, MON, 2), "Canberra Day" ) def get_queens_birthday(self, year): return ( Australia.get_nth_weekday_in_month(year, 6, MON, 2), "Queen's Birthday" ) def get_labour_day_october(self, year): return ( Australia.get_nth_weekday_in_month(year, 10, MON), 'Labour Day' ) def get_anzac_day(self, year): anzac_day = date(year, 4, 25) if not self.shift_anzac_day: return anzac_day, "Anzac Day" if anzac_day.weekday() in self.ANZAC_SHIFT_DAYS: anzac_day = self.find_following_working_day(anzac_day) return anzac_day, "Anzac Day" def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) january_first = date(year, 1, 1) if january_first.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(january_first), "New Year's Day shift") ) australia_day = date(year, 1, 26) if australia_day.weekday() in self.get_weekend_days(): days.append(( self.find_following_working_day(australia_day), "Australia Day shift") ) # was fixed, but might be shifted days.append(self.get_anzac_day(year)) if self.include_queens_birthday: days.append(self.get_queens_birthday(year)) if self.include_labour_day_october: days.append(self.get_labour_day_october(year)) christmas = date(year, 12, 25) boxing_day = date(year, 12, 26) if christmas.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(christmas) days.append((shift, "Christmas Shift")) days.append((shift + timedelta(days=1), "Boxing Day Shift")) elif boxing_day.weekday() in self.get_weekend_days(): shift = self.find_following_working_day(boxing_day) days.append((shift, "Boxing Day Shift")) return days @iso_register('AU-ACT') class AustralianCapitalTerritory(Australia): "Australian Capital Territory" include_easter_saturday = True include_queens_birthday = True include_labour_day_october = True include_boxing_day = True _family_community_label = "Family & Community Day" def get_family_community_day(self, year): """ Return Family & Community Day. see: https://en.wikipedia.org/wiki/Family_Day#Australia """ # Since this day is picked unsing the school year calendar, there's no # mathematical way yet to compute it. # This public holiday was declared in 2007. [..] # Per Holidays (Reconciliation Day) Amendment Bill 2017, 2017 is the # last year that ACT will celebrate family and community day. It is # being replaced by Reconciliaton day. if year < 2007 or year > 2018: # This would be interpreted as "this holiday must not be added" return None # Family & Community Day was celebrated on the first Tuesday of # November in 2007, 2008 and 2009 if year in (2007, 2008, 2009): day = AustralianCapitalTerritory.get_nth_weekday_in_month( year, 11, TUE) # Family & Community Day was celebrated on the last Monday of # November in 2010, 2013, 2014, 2015, 2016, 2017 elif year in (2010, 2013, 2014, 2015, 2016, 2017): day = AustralianCapitalTerritory.get_last_weekday_in_month( year, 9, MON) # Family & Community Day was celebrated on the second Monday of # October in 2011 and 2012 elif year in (2011, 2012): day = AustralianCapitalTerritory.get_nth_weekday_in_month( year, 10, MON, 2) else: # If for some reason the year is not correctly provided # (not and int, or whatever) return None return day, self._family_community_label def get_reconciliation_day(self, year): """ Return Reconciliaton Day. As of 2018, it replaces Family & Community Day. """ if year < 2018: return None reconciliation_day = date(year, 5, 27) if reconciliation_day.weekday() == MON: return reconciliation_day, "Reconciliation Day" else: shift = AustralianCapitalTerritory.get_first_weekday_after( reconciliation_day, MON) return shift, "Reconciliation Day Shift" def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_canberra_day(year)) family_community_day = self.get_family_community_day(year) if family_community_day is not None: days.append(family_community_day) reconciliation_day = self.get_reconciliation_day(year) if reconciliation_day is not None: days.append(reconciliation_day) return days @iso_register('AU-NSW') class NewSouthWales(Australia): "New South Wales" include_queens_birthday = True include_easter_saturday = True include_easter_sunday = True include_labour_day_october = True include_boxing_day = True ANZAC_SHIFT_DAYS = (SUN,) @iso_register('AU-NT') class NorthernTerritory(Australia): "Northern Territory" include_easter_saturday = True include_queens_birthday = True include_boxing_day = True ANZAC_SHIFT_DAYS = (SUN,) def get_may_day(self, year): return ( NorthernTerritory.get_nth_weekday_in_month(year, 5, MON), "May Day" ) def get_picnic_day(self, year): return ( NorthernTerritory.get_nth_weekday_in_month(year, 8, MON), "Picnic Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ self.get_may_day(year), self.get_picnic_day(year), ]) return days @iso_register('AU-QLD') class Queensland(Australia): "Queensland" include_easter_saturday = True include_queens_birthday = True include_boxing_day = True ANZAC_SHIFT_DAYS = (SUN,) def get_labour_day_may(self, year): return ( Queensland.get_nth_weekday_in_month(year, 5, MON), "Labour Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_labour_day_may(year)) return days @iso_register('AU-SA') class SouthAustralia(Australia): "South Australia" include_easter_saturday = True include_queens_birthday = True include_labour_day_october = True ANZAC_SHIFT_DAYS = (SUN,) def get_adelaides_cup(self, year): return ( SouthAustralia.get_nth_weekday_in_month(year, 3, MON, 2), "Adelaide's cup" ) def get_proclamation_day(self, year): return date(year, 12, 26), "Proclamation Day" def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ self.get_adelaides_cup(year), self.get_proclamation_day(year), ]) return days @iso_register('AU-TAS') class Tasmania(Australia): "Tasmania" include_queens_birthday = True include_boxing_day = True shift_anzac_day = False @property def has_recreation_day(self): return True def get_eight_hours_day(self, year): return ( Tasmania.get_nth_weekday_in_month(year, 3, MON, 2), "Eight hours Day" ) def get_recreation_day(self, year): return ( Tasmania.get_nth_weekday_in_month(year, 11, MON), "Recreation Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_eight_hours_day(year)) if self.has_recreation_day: days.append(self.get_recreation_day(year)) return days class Hobart(Tasmania): "Hobart" @property def has_recreation_day(self): return False def get_hobart(self, year): return ( Hobart.get_nth_weekday_in_month(year, 2, MON, 2), "Royal Hobart Regatta" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_hobart(year)) return days @iso_register('AU-VIC') class Victoria(Australia): "Victoria" include_easter_saturday = True include_queens_birthday = True include_boxing_day = True shift_anzac_day = False def get_labours_day_in_march(self, year): return ( Victoria.get_nth_weekday_in_month(year, 3, MON, 2), "Labour Day" ) def get_melbourne_cup(self, year): return ( Victoria.get_nth_weekday_in_month(year, 11, TUE), "Melbourne Cup" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_labours_day_in_march(year)) days.append(self.get_melbourne_cup(year)) return days @iso_register('AU-WA') class WesternAustralia(Australia): "Western Australia" include_boxing_day = True def get_labours_day_in_march(self, year): return ( WesternAustralia.get_nth_weekday_in_month(year, 3, MON), "Labour Day" ) def get_western_australia_day(self, year): return ( WesternAustralia.get_nth_weekday_in_month(year, 6, MON), "Western Australia Day" ) def get_variable_days(self, year): # It is not possible to surely compute Queen's Birthday holiday in # The western Australia territory, since it's based on the Governor # Decision (it is typically the last Monday of September or the first # Monday of October) days = super().get_variable_days(year) days.append(self.get_labours_day_in_march(year)) days.append(self.get_western_australia_day(year)) return days calendra-7.9.0/calendra/oceania/marshall_islands.py000066400000000000000000000020011457013633400223410ustar00rootroot00000000000000from ..core import WesternCalendar, FRI from ..registry_tools import iso_register @iso_register('MH') class MarshallIslands(WesternCalendar): "Marshall Islands" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (3, 3, "Remembrance Day"), (5, 1, "Constitution Day"), (11, 17, "Presidents' Day"), (12, 31, "New Year's Eve"), ) include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append(( MarshallIslands.get_nth_weekday_in_month(year, 7, FRI), "Fishermen's Holiday" )) days.append(( MarshallIslands.get_nth_weekday_in_month(year, 9, FRI), "Labour Day" )) days.append(( MarshallIslands.get_last_weekday_in_month(year, 9, FRI), "Manit Day" )) days.append(( MarshallIslands.get_nth_weekday_in_month(year, 12, FRI), "Gospel Day" )) return days calendra-7.9.0/calendra/oceania/new_zealand.py000066400000000000000000000025101457013633400213150ustar00rootroot00000000000000from datetime import date from dateutil import relativedelta as rd from ..core import WesternCalendar, ChristianMixin from ..core import Holiday from ..registry_tools import iso_register @iso_register("NZ") class NewZealand(WesternCalendar, ChristianMixin): "New Zealand" include_good_friday = True include_easter_monday = True include_boxing_day = True shift_new_years_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( Holiday(date(2000, 2, 6), "Waitangi Day"), Holiday(date(2000, 4, 25), "ANZAC Day"), ) def get_queens_birthday(self, year): return Holiday( date(year, 6, 1) + rd.relativedelta(weekday=rd.MO(1)), "Queen's Birthday", indication="First Monday in June", ) def get_labour_day(self, year): return Holiday( date(year, 10, 1) + rd.relativedelta(weekday=rd.MO(4)), "Labour Day", indication="Fourth Monday in October", ) def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) days.append(Holiday( date(year, 1, 2), "Day after New Year's Day", )) days.append(self.get_queens_birthday(year)) days.append(self.get_labour_day(year)) return days calendra-7.9.0/calendra/precomputed_astronomy.py000066400000000000000000000075621457013633400221050ustar00rootroot00000000000000""" Astronomical functions Computed years spread from 30 years before and after the release year. """ import datetime import gzip import json import pathlib from typing import Tuple TZAwareDate = datetime.date # In 2021, Skyfield cannot compute ephemeris after date 2053-10-08 23:58:51Z UT YEAR_INTERVAL = 30 TIME_ZONES = ( 'America/Santiago', 'Asia/Hong_Kong', 'Asia/Taipei', 'Asia/Tokyo', ) pre_computed_equinoxes_path = \ pathlib.Path(__file__).parent / 'equinoxes.json.gz' pre_computed_solar_terms_path = \ pathlib.Path(__file__).parent / 'solar_terms.json.gz' try: # Before Python 3.7, date.fromisoformat does not exist datetime.date.fromisoformat def fromisoformat(iso): return datetime.date.fromisoformat(iso) except AttributeError: # pre-3.7 def fromisoformat(iso): try: if not iso or '-' not in iso: raise ValueError parts = [int(x) for x in iso.split('-')] if len(parts) != 3: raise ValueError return datetime.date(year=parts[0], month=parts[1], day=parts[2]) except ValueError: raise ValueError(f"Invalid isoformat string: '{iso}'") def create_astronomical_data(progress=None): from .skyfield_astronomy import ( calculate_equinoxes as real_calculate_equinoxes ) from .skyfield_astronomy import ( solar_term as real_solar_term ) if progress is None: progress = lambda it: it # noqa: E731 current_year = datetime.date.today().year first_year = current_year - YEAR_INTERVAL last_year = current_year + YEAR_INTERVAL years = range(first_year, last_year + 1) equinoxes = dict() solar_terms = dict() for i, time_zone in enumerate(TIME_ZONES, 1): print(f"{time_zone} {i}/{len(TIME_ZONES)}") equinoxes[time_zone] = dict() equinoxes_tz = equinoxes[time_zone] solar_terms[time_zone] = dict() solar_terms_tz = solar_terms[time_zone] for year in progress(years): equinoxes_tz[year] = tuple( equinox.isoformat() for equinox in real_calculate_equinoxes(year, time_zone) ) solar_terms_tz[year] = dict() for degrees in range(15, 360, 15): solar_terms_tz[year][degrees] = \ real_solar_term(year, degrees, time_zone).isoformat() with gzip.open(pre_computed_equinoxes_path, 'wb') as f: f.write(json.dumps(equinoxes, ensure_ascii=False).encode('utf-8')) with gzip.open(pre_computed_solar_terms_path, 'wb') as f: f.write(json.dumps(solar_terms, ensure_ascii=False).encode('utf-8')) def calculate_equinoxes( year: int, timezone: str = 'UTC', ) -> Tuple[TZAwareDate, TZAwareDate]: """ calculate equinox with time zone. returns a 2-tuple with vernal and autumn equinoxes. """ equinoxes = json.loads(gzip.decompress( pre_computed_equinoxes_path.read_bytes() ).decode('utf-8')) try: result = equinoxes[timezone][str(year)] except KeyError: raise NotImplementedError( f"The year {year} and timezone {timezone} are not pre-computed" ) return tuple(fromisoformat(equinox) for equinox in result) def solar_term(year: int, degrees: int, timezone: str = 'UTC') -> TZAwareDate: if not 15 <= degrees < 345 or degrees % 15 != 0: raise ValueError( "The degrees should be between 15 and 345 by step of 15" ) solar_terms = json.loads(gzip.decompress( pre_computed_solar_terms_path.read_bytes() ).decode('utf-8')) try: solar_terms_per_tz_and_year = solar_terms[timezone][str(year)] except KeyError: raise NotImplementedError( f"The year {year} and timezone {timezone} are not pre-computed" ) return fromisoformat( solar_terms_per_tz_and_year[str(degrees)] ) calendra-7.9.0/calendra/registry.py000066400000000000000000000105011457013633400172760ustar00rootroot00000000000000from importlib import import_module from .core import Calendar from .exceptions import ISORegistryError class IsoRegistry: """ Registry for all calendars retrievable by ISO 3166-2 codes associated with countries where they are used as official calendars. Two letter codes are favored for any subdivisions. """ STANDARD_MODULES = ( # Europe Countries 'europe', # United States of America 'usa', # American continent outside of USA 'america', # African continent 'africa', # Asia 'asia', # Oceania 'oceania', ) def __init__(self, load_standard_modules=False): self.region_registry = dict() if load_standard_modules: for module_name in self.STANDARD_MODULES: module = f'calendra.{module_name}' all_classes = getattr(import_module(module), '__all__') self.load_module_from_items(module, all_classes) def register(self, iso_code, cls): """ Store the ``cls`` in the region_registry. """ if not issubclass(cls, Calendar): raise ISORegistryError( f"Class `{cls}` is not a Calendar class" ) self.region_registry[iso_code] = cls def load_module_from_items(self, module_name, items): """ Load all registered classes in the registry """ for item in items: cls = getattr(import_module(module_name), item) iso_stuff = getattr(cls, '__iso_code', None) if iso_stuff: iso_code, class_name = iso_stuff if iso_code and cls.__name__ == class_name: self.register(iso_code, cls) def get(self, iso_code): """ Retrieve calendar class associated with given ``iso_code``. If calendar of subdivision is not registered (for subdivision like ISO codes, e.g. GB-ENG) returns calendar of containing region (e.g. United Kingdom for ISO code GB) if it's available. :rtype: Calendar """ return self.region_registry.get(iso_code) def get_subregions(self, iso_code): """ Returns subregion calendar classes for given region iso_code. >>> registry = IsoRegistry() >>> # assuming calendars registered are: DE, DE-HH, DE-BE >>> registry.get_subregions('DE') # doctest: +SKIP {'DE-HH': , 'DE-BE': } :rtype dict :return dict where keys are ISO codes strings and values are calendar classes """ items = dict() for key, value in self.region_registry.items(): if key.startswith(f"{iso_code}-"): items[key] = value return items def get_calendars(self, region_codes=None, include_subregions=False): """ Returns calendar classes for regions :param region_codes list of ISO codes for selected regions. If empty, the function will return all items from the registry. :param include_subregions boolean if subregions of selected regions should be included in result :rtype dict :return dict where keys are ISO codes strings and values are calendar classes """ if not region_codes: # Here it contains all subregions if include_subregions: return self.region_registry.copy() items = {k: v for k, v in self.region_registry.items() if '-' not in k} return items items = dict() for code in region_codes: try: items[code] = self.region_registry[code] except KeyError: continue if include_subregions: items.update(self.get_subregions(code)) return items registry = IsoRegistry() # Europe Countries from calendra.europe import * # noqa # United States of America from calendra.usa import * # noqa # American continent outside of USA from calendra.america import * # noqa # African continent from calendra.africa import * # noqa from calendra.asia import * # noqa from calendra.oceania import * # noqa calendra-7.9.0/calendra/registry_tools.py000066400000000000000000000013151457013633400205210ustar00rootroot00000000000000""" Tools to update the ISO registry. """ def iso_register(iso_code): """ Registers Calendar class as country or region in IsoRegistry. Registered country must set class variables ``iso`` using this decorator. >>> from calendra.core import Calendar >>> from calendra.registry import registry >>> from calendra.registry_tools import iso_register >>> @iso_register('MC-MR') ... class MyRegion(Calendar): ... 'My Region' Region calendar is then retrievable from registry: >>> calendar = registry.get('MC-MR') """ def wrapper(cls): from calendra.registry import registry registry.register(iso_code, cls) return cls return wrapper calendra-7.9.0/calendra/ruff.toml000066400000000000000000000000311457013633400167100ustar00rootroot00000000000000[format] exclude = ["*"] calendra-7.9.0/calendra/skyfield_astronomy.py000066400000000000000000000106551457013633400213650ustar00rootroot00000000000000""" Astronomical functions """ from math import pi, radians, tau try: # As of Python 3.9, included in the stdlib from zoneinfo import ZoneInfo except ImportError: # pre-3.9 from backports.zoneinfo import ZoneInfo from skyfield.api import Loader from skyfield import almanac from skyfield_data import get_skyfield_data_path from datetime import date, timedelta # Parameter for the newton method to converge towards the closest solution # to the function. By default it'll be an approximation of a 10th of a second. hour = 1 / 24 minute = hour / 60 second = minute / 60 newton_precision = second / 10 def calculate_equinoxes(year, timezone='UTC'): """ calculate equinox with time zone """ tz = ZoneInfo(timezone) load = Loader(get_skyfield_data_path()) ts = load.timescale() planets = load('de421.bsp') t0 = ts.utc(year, 1, 1) t1 = ts.utc(year, 12, 31) datetimes, _ = almanac.find_discrete(t0, t1, almanac.seasons(planets)) vernal_equinox = datetimes[0].astimezone(tz).date() autumn_equinox = datetimes[2].astimezone(tz).date() return vernal_equinox, autumn_equinox def get_current_longitude(current_date, earth, sun): """ Return the ecliptic longitude, in radians. """ astrometric = earth.at(current_date).observe(sun) latitude, longitude, _ = astrometric.ecliptic_latlon(epoch='date') return longitude.radians def newton(f, x0, x1, precision=newton_precision, **func_kwargs): """Return an x-value at which the given function reaches zero. Stops and declares victory once the x-value is within ``precision`` of the solution, which defaults to a half-second of clock time. """ f0, f1 = f(x0, **func_kwargs), f(x1, **func_kwargs) while f1 and abs(x1 - x0) > precision and f1 != f0: new_x1 = x1 + (x1 - x0) / (f0 / f1 - 1) x0, x1 = x1, new_x1 f0, f1 = f1, f(x1, **func_kwargs) return x1 def newton_angle_function(t, ts, target_angle, body1, body2): """ Compute the longitude of body2 relative to body1 In our case, it's Earth & Sun, but it could be used as any other combination of solar system planets/bodies. """ # We've got a float which is the `tt` sky_tt = ts.tt_jd(t) longitude = get_current_longitude(sky_tt, body1, body2) result = target_angle - longitude if result > pi: result = result - pi if result < -pi: result = result + pi return result def solar_term(year, degrees, timezone='UTC'): """ Returns the date of the solar term for the given longitude and the given year. Solar terms are used for Chinese and Taiwanese holidays (e.g. Qingming Festival in Taiwan). More information: - https://en.wikipedia.org/wiki/Solar_term - https://en.wikipedia.org/wiki/Qingming This function is adapted from the following topic: https://answers.launchpad.net/pyephem/+question/110832 """ # Target angle as radians target_angle = radians(degrees) load = Loader(get_skyfield_data_path()) planets = load('de421.bsp') earth = planets['earth'] sun = planets['sun'] ts = load.timescale() tz = ZoneInfo(timezone) jan_first = ts.utc(date(year, 1, 1)) current_longitude = get_current_longitude(jan_first, earth, sun) # Find approximately the right time of year. difference = (target_angle - current_longitude) % tau # Here we have an approximation of the number of julian days to go date_delta = 365.25 * difference / tau # convert to "tt" and reconvert it back to a Time object t0 = ts.tt_jd(jan_first.tt + date_delta) # Using datetimes to compute the next step date t0_plus_one_minute = t0.utc_datetime() + timedelta(minutes=1) # Back to Skyfield Time objects t0_plus_one_minute = ts.utc(t0_plus_one_minute) # Julian day for the starting date t0 = t0.tt # Adding one minute to have a second boundary t0_plus_one_minute = t0_plus_one_minute.tt # Newton method to converge towards the target angle t = newton( newton_angle_function, t0, t0_plus_one_minute, precision=newton_precision, # Passed as kwargs to the angle function ts=ts, target_angle=target_angle, body1=earth, body2=sun, ) # Here we have a float to convert to julian days. t = ts.tt_jd(t) # To convert to datetime t = t.utc_datetime() # Convert in the timezone result = t.astimezone(tz) return result.date() calendra-7.9.0/calendra/solar_terms.json.gz000066400000000000000000000162221457013633400207260ustar00rootroot00000000000000`solar_terms.jsonMGvFʠύ/fgaA]o(͓V`{u`8O?ovz_K.g~xW+~W/gn}<wvaC\ur>z~>/Oxv><~~Kgz\ݟ/r}7r}x]5f<^m<^??Ϙ sLΎ?&~w kW~7.g~O f'O~Y~y//͘0;a~:< f\gO~ٯ:o1;avg̚1 0 0 0 0 0fffffff,,,EEE?ߌY31`0\0]A0]A. A0a0a0as1x `. a.\s!̅0\s!̅0\sB ]څ.2c3 _sK v̕JvJv%̕.Jos%̕0Wz+]ڕJ+a:cn3`n}͍07s#̍07knF_s#̍07mnti7یϘ;`piwNv'̝0w;atiw s'̝0w;a s'}}͘Ϧ8<]χ|0?Nqx|8]O=_q>ti?N_t|8a>O8l3f 0`6|k[F0a6lւ=N_qx8lݼ~>Ϙ0>n0>n0;aK \-ff'N~>cåmpiwmtiw Vg̝.N;}͝Nos5w s'̝>c3`5<yA}̓0< ̃A_yAa6}ͳقXl ,3` ]6`F8<]FȂ..8$Z6򠶗moAAm9Z Z^=EAm1jm{yP-AEyоuʃ<c6z|?jyFyP-AջA}5zLɂ-Ab.AVTyо ʃw̓AACe#j{yжmyNyPQQ y|?jyP$Z򠶗myжAA}/Z Z^=}󠶘5ʃ< returns the value as a string var_contents = self.cal.export_to_ical(period=[2019, 2020]) file_contents = test_path.read_text() assert file_contents == var_contents # If platform is Windows close the temp file descriptor if system() == 'Windows': # pragma: no cover os.close(test_file_fd) # Remove the .ics file if this test passes test_path.unlink() calendra-7.9.0/calendra/tests/test_africa.py000066400000000000000000000734711457013633400210730ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..africa import ( Algeria, Angola, Benin, IvoryCoast, Kenya, Madagascar, Nigeria, SaoTomeAndPrincipe, SouthAfrica, Tunisia, ) from ..core import MON, FRI from ..exceptions import CalendarError class TunisiaTest(GenericCalendarTest): cal_class = Tunisia def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 20), holidays) # Independance Day self.assertIn(date(2013, 7, 25), holidays) # Republic Day self.assertIn(date(2013, 1, 24), holidays) # Milad un Nabi self.assertIn(date(2013, 8, 8), holidays) # Eid ul-fitr self.assertIn(date(2013, 8, 9), holidays) # Eid ul-fitr next day self.assertIn(date(2013, 10, 15), holidays) # Evacuation Day def test_year_2022(self): holidays = self.cal.holidays_set(2022) self.assertIn(date(2022, 3, 20), holidays) # Independance Day self.assertIn(date(2022, 7, 25), holidays) # Republic Day self.assertIn(date(2022, 10, 8), holidays) # Milad un Nabi self.assertIn(date(2022, 5, 3), holidays) # Eid ul-fitr self.assertIn(date(2022, 5, 4), holidays) # Eid ul-fitr next day self.assertIn(date(2022, 10, 15), holidays) # Evacuation Day def test_revolution_day(self): holidays = self.cal.holidays_set(2013) self.assertNotIn(date(2013, 12, 17), holidays) # Revolution Day self.assertIn(date(2013, 1, 14), holidays) # Revolution Day holidays = self.cal.holidays_set(2022) self.assertIn(date(2022, 12, 17), holidays) # Revolution Day self.assertNotIn(date(2022, 1, 14), holidays) # Revolution Day holidays = self.cal.holidays_set(2010) self.assertNotIn(date(2010, 12, 17), holidays) # Revolution Day self.assertNotIn(date(2010, 1, 14), holidays) # Revolution Day class AlgeriaTest(GenericCalendarTest): cal_class = Algeria def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New year self.assertIn(date(2013, 1, 24), holidays) # Milad un Nabi self.assertIn(date(2013, 5, 1), holidays) # Labour day self.assertIn(date(2013, 7, 5), holidays) # Independence day self.assertIn(date(2013, 8, 8), holidays) # Eid ul-fitr self.assertIn(date(2013, 10, 15), holidays) # Eid el-ada self.assertIn(date(2013, 11, 1), holidays) # Anniversary revolution self.assertIn(date(2013, 11, 5), holidays) # New Year self.assertIn(date(2013, 11, 14), holidays) # Ashura class BeninTest(GenericCalendarTest): cal_class = Benin def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 9), holidays) # Ascension self.assertIn(date(2013, 5, 20), holidays) # Whit Monday self.assertIn(date(2013, 5, 1), holidays) # Labour day self.assertIn(date(2013, 8, 1), holidays) # Independence Day self.assertIn(date(2013, 8, 15), holidays) # Assumption self.assertIn(date(2013, 10, 26), holidays) # Armed Forces Day self.assertIn(date(2013, 11, 1), holidays) # All Saints Day self.assertIn(date(2013, 11, 30), holidays) # National Day self.assertIn(date(2013, 12, 25), holidays) # christmas # Variable Muslim days self.assertIn(date(2013, 1, 24), holidays) # Milad un Nabi self.assertIn(date(2013, 10, 15), holidays) # Tabaski self.assertIn(date(2013, 8, 8), holidays) # Eid al-Fitr class SouthAfricaTest(GenericCalendarTest): cal_class = SouthAfrica def test_before_1910(self): with self.assertRaises(CalendarError): self.cal.holidays_set(1909) def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 3, 21), holidays) # human rights day self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 4, 1), holidays) # Easter monday / Family day self.assertIn(date(2013, 4, 27), holidays) # freedom day self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 6, 16), holidays) # youth day self.assertNotIn(date(2013, 6, 17), holidays) # youth day - observed self.assertIn(date(2013, 8, 9), holidays) # national women's day self.assertIn(date(2013, 9, 24), holidays) # heritage day self.assertIn(date(2013, 12, 16), holidays) # day of reconciliation self.assertIn(date(2013, 12, 25), holidays) # christmas self.assertIn(date(2013, 12, 26), holidays) # day of goodwill # test that Youth Day is observed on 17-Jun and is not a working day observed = self.cal.observed_holidays(2013) self.assertIn(date(2013, 6, 17), observed) self.assertFalse(self.cal.is_working_day(date(2013, 6, 17))) def test_year_2014(self): # test shifting holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 27), holidays) # freedom day self.assertNotIn(date(2014, 4, 28), holidays) # freedom day - observ # test that Freedom Day is observed on 28-Apr and is not a working day observed = self.cal.observed_holidays(2014) self.assertIn(date(2014, 4, 28), observed) self.assertFalse(self.cal.is_working_day(date(2014, 4, 28))) def test_easter_monday(self): # 1910-1979, Easter Monday label was "Easter Monday" holidays = self.cal.holidays(1979) easter_monday_1979 = date(1979, 4, 16) holidays_dates = [item[0] for item in holidays] self.assertEqual(holidays_dates.count(easter_monday_1979), 1, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[easter_monday_1979], "Easter Monday") # From 1980 to "now", it's Family Day holidays = self.cal.holidays(1980) # Since the Founders' day is a Sunday, the same date appears twice # The second one is a substitute holidays = [item for item in holidays if item[1] != "Founder's Day substitute"] easter_monday_1980 = date(1980, 4, 7) holidays_dates = [item[0] for item in holidays] self.assertEqual(holidays_dates.count(easter_monday_1980), 1, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[easter_monday_1980], "Family Day") def test_april_6th(self): # 1951, no April 6th holidays = self.cal.holidays(1951) holidays_dates = [item[0] for item in holidays] april_6th = date(1951, 4, 6) self.assertNotIn(april_6th, holidays_dates, holidays) # 1952-1973, it was named Van Riebeeck's day holidays = self.cal.holidays(1952) holidays_dates = [item[0] for item in holidays] april_6th = date(1952, 4, 6) self.assertIn(april_6th, holidays_dates, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[april_6th], "Van Riebeeck's Day") # 1974: No April 6th holidays = self.cal.holidays(1974) holidays_dates = [item[0] for item in holidays] april_6th = date(1974, 4, 6) self.assertNotIn(april_6th, holidays_dates, holidays) # 1980-1994, it became Founder's day holidays = self.cal.holidays(1980) holidays_dates = [item[0] for item in holidays] april_6th = date(1980, 4, 6) self.assertIn(april_6th, holidays_dates, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[april_6th], "Founder's Day") # 1995, no April 6th holidays = self.cal.holidays(1995) holidays_dates = [item[0] for item in holidays] april_6th = date(1995, 4, 6) self.assertNotIn(april_6th, holidays_dates, holidays) def test_workers_day(self): # No Workers' day before 1987 holidays = self.cal.holidays(1986) holidays_labels = [item[1] for item in holidays] self.assertNotIn("Workers' Day", holidays_labels, holidays) # 1987-1989: 1st Friday in May holidays = self.cal.holidays(1987) holidays_dates = [item[0] for item in holidays] first_friday_may = self.cal.get_nth_weekday_in_month(1987, 5, FRI) self.assertIn(first_friday_may, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[first_friday_may], "Workers' Day") # 1990-1994: No Workers' day holidays = self.cal.holidays(1990) holidays_labels = [item[1] for item in holidays] self.assertNotIn("Workers' Day", holidays_labels, holidays) # as of 1995: Workers' day is on May 1st holidays = self.cal.holidays(1995) holidays_dates = [item[0] for item in holidays] first_may = date(1995, 5, 1) self.assertIn(first_may, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[first_may], "Workers' Day") def test_ascension_day(self): # Before 1993 (included), Ascension day was a holiday holidays = self.cal.holidays(1993) holidays_dates = [item[0] for item in holidays] ascension_1993 = self.cal.get_ascension_thursday(1993) self.assertIn(ascension_1993, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[ascension_1993], "Ascension Day") # After 1993, no more Ascension day holidays = self.cal.holidays(1994) holidays_dates = [item[0] for item in holidays] ascension_1994 = self.cal.get_ascension_thursday(1994) self.assertNotIn(ascension_1994, holidays_dates) def test_victoria_empire_day(self): # 1910–1951: 24 May is Victoria Day / Empire Day holidays = self.cal.holidays(1951) holidays_dates = [item[0] for item in holidays] may_24th_1951 = date(1951, 5, 24) self.assertIn(may_24th_1951, holidays_dates, holidays) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[may_24th_1951], "Victoria Day / Empire Day") # 1952-present, no Victoria / Empire day holidays = self.cal.holidays(1952) holidays_dates = [item[0] for item in holidays] may_24th_1952 = date(1952, 5, 24) self.assertNotIn(may_24th_1952, holidays_dates, holidays) def test_may_31st(self): # 1910-1960, it's Union Day holidays = self.cal.holidays(1960) holidays_dates = [item[0] for item in holidays] may_31st_1960 = date(1960, 5, 31) self.assertIn(may_31st_1960, holidays_dates, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[may_31st_1960], "Union Day") # 1961-1993, it's Republic Day holidays = self.cal.holidays(1993) holidays_dates = [item[0] for item in holidays] may_31st_1993 = date(1993, 5, 31) self.assertIn(may_31st_1993, holidays_dates, holidays) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[may_31st_1993], "Republic Day") # As of 1994, no more may 31st holidays = self.cal.holidays(1994) holidays_dates = [item[0] for item in holidays] may_31st_1994 = date(1994, 5, 31) self.assertNotIn(may_31st_1994, holidays_dates, holidays) def test_queens_birthday(self): # Before 1952, no Queens Birthday holidays = self.cal.holidays(1951) holidays_dates = [item[0] for item in holidays] july_2nd_monday = self.cal.get_nth_weekday_in_month(1951, 7, MON, 2) self.assertNotIn(july_2nd_monday, holidays_dates) # 1952–1960: 2nd Monday in July is Queen's Birthday for year in (1952, 1959, 1960): # interval of the years holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] july_2nd_monday = self.cal.get_nth_weekday_in_month( year, 7, MON, 2) self.assertIn(july_2nd_monday, holidays_dates) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[july_2nd_monday], "Queen's Birthday" ) # After 1961, no more Queen's Birthday for year in (1961, 1962, 2008, 2018): # interval of the years holidays = self.cal.holidays(year) holidays_labels = [item[1] for item in holidays] self.assertNotIn("Queen's Birthday", holidays_labels) def test_womens_day_label(self): holidays = self.cal.holidays(2018) womens_day = date(2018, 8, 9) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[womens_day], "National Women's Day" ) def test_family_day_in_july(self): # Before 1961, no Family day in July holidays = self.cal.holidays(1960) holidays_dates = [item[0] for item in holidays] family_day = date(1960, 7, 10) self.assertNotIn(family_day, holidays_dates) # From 1961 to 1973, Family day is on July 10th for year in (1961, 1970, 1973): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] family_day = date(year, 7, 10) self.assertIn(family_day, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[family_day], "Family Day") # As of 1974, no more for year in (1974, 1980, 1990, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] family_day = date(year, 7, 10) self.assertNotIn(family_day, holidays_dates) def test_king_birthday(self): # From 1910 to 1951, 1st Monday in August for year in (1910, 1935, 1951): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] king_birthday = self.cal.get_nth_weekday_in_month(year, 8, MON) self.assertIn(king_birthday, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[king_birthday], "King's Birthday") # Not after 1952 for year in (1952, 1960, 1990, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] king_birthday = self.cal.get_nth_weekday_in_month(year, 8, MON) self.assertNotIn(king_birthday, holidays_dates) def test_settlers_day(self): # Before 1952, no settler's day holidays = self.cal.holidays(1951) holidays_dates = [item[0] for item in holidays] settlers_day = self.cal.get_nth_weekday_in_month(1951, 9, MON) self.assertNotIn(settlers_day, holidays_dates) # From 1952 to 1979, 1st Monday in August for year in (1952, 1960, 1952, 1979): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] settlers_day = self.cal.get_nth_weekday_in_month(year, 9, MON) self.assertIn(settlers_day, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[settlers_day], "Settlers' Day") # Not after 1979 for year in (1980, 1990, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] settlers_day = self.cal.get_nth_weekday_in_month(year, 9, MON) self.assertNotIn(settlers_day, holidays_dates) def test_kruger_day(self): # Not before 1952 holidays = self.cal.holidays(1951) holidays_dates = [item[0] for item in holidays] kruger_day = date(1951, 10, 10) self.assertNotIn(kruger_day, holidays_dates) # Kruger Day was on October 10th 1952-1993 for year in (1952, 1960, 1952, 1979, 1993): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] kruger_day = date(year, 10, 10) self.assertIn(kruger_day, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[kruger_day], "Kruger Day") # As of 1994, not anymore for year in (1994, 2000, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] kruger_day = date(year, 10, 10) self.assertNotIn(kruger_day, holidays_dates) def test_december_16th(self): # from 1910 to 1951, it's "Dingaan's Day" for year in (1910, 1930, 1951): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_16th = date(year, 12, 16) self.assertIn(december_16th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[december_16th], "Dingaan's Day") # from 1952 to 1979 it's the "Day of the Covenant" for year in (1952, 1960, 1979): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_16th = date(year, 12, 16) self.assertIn(december_16th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[december_16th], "Day of the Covenant") # from 1980 to 1994 it's the "Day of the Vow" # NOTE: wikipedia states it starts at year 1979, but that would mean # there were two labels on the same year, which would be wrong. # We may wait to see if this error is fixed one day. for year in (1980, 1990, 1994): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_16th = date(year, 12, 16) self.assertIn(december_16th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[december_16th], "Day of the Vow") # As of 1995, it's the "Day of Reconciliation" for year in (1995, 2000, 2010, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_16th = date(year, 12, 16) self.assertIn(december_16th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[december_16th], "Day of Reconciliation") def test_december_26th(self): # from 1910 to 1979, it's "Boxing Day" # Year 1910 is excluded, since Christmas was on a Sunday, and shift # rules apply for year in (1911, 1930, 1951, 1979): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_26th = date(year, 12, 26) self.assertIn(december_26th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[december_26th], "Boxing Day", year) # As of 1980, it's "Day of Goodwill" for year in (1980, 1990, 1995, 2000, 2018): holidays = self.cal.holidays(year) holidays_dates = [item[0] for item in holidays] december_26th = date(year, 12, 26) self.assertIn(december_26th, holidays_dates) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[december_26th], "Day of Goodwill") def test_special_1999(self): # National and provincial government elections – 2 June 1999 holidays = self.cal.holidays_set(1999) self.assertIn(date(1999, 6, 2), holidays) # December 31st was a "Y2K" holiday self.assertIn(date(1999, 12, 31), holidays) def test_special_2000(self): holidays = self.cal.holidays_set(2000) # Holiday added to celebrate Y2K self.assertIn(date(2000, 1, 2), holidays) # Shift day because Jan 2nd was a sunday self.assertIn(date(2000, 1, 3), holidays) def test_special_2001(self): holidays = self.cal.holidays_set(2001) # Holiday added to celebrate Y2K self.assertIn(date(2001, 1, 2), holidays) def test_special_2004(self): # National and provincial government elections – 14 April 2004 holidays = self.cal.holidays_set(2004) self.assertIn(date(2004, 4, 14), holidays) def test_special_2006(self): # Local government elections – 1 March 2006 holidays = self.cal.holidays_set(2006) self.assertIn(date(2006, 3, 1), holidays) def test_special_2008(self): # 2 May 2008 was declared a public holiday when Human Rights Day # and Good Friday coincided on 21 March 2008. holidays = self.cal.holidays_set(2008) self.assertIn(date(2008, 5, 2), holidays) def test_special_2009(self): # National and provincial government elections – 22 April 2009 holidays = self.cal.holidays_set(2009) self.assertIn(date(2009, 4, 22), holidays) def test_special_2011(self): # Local government elections – 18 May 2011 holidays = self.cal.holidays_set(2011) self.assertIn(date(2011, 5, 18), holidays) # 27 December 2011 was declared a holiday by president Motlanthe self.assertIn(date(2011, 12, 27), holidays) def test_special_2014(self): # National and provincial government elections – 7 May 2014 holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 5, 7), holidays) def test_special_2016(self): # Local government elections – 3 August 2016 holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 8, 3), holidays) def test_special_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 5, 8), holidays) # 2019 National Elections # Only in 2019 holidays = self.cal.holidays_set(2017) self.assertNotIn(date(2017, 5, 8), holidays) class MadagascarTest(GenericCalendarTest): cal_class = Madagascar def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 3, 29), holidays) # martyrs day self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 5, 9), holidays) # ascension self.assertIn(date(2013, 5, 20), holidays) # whit monday self.assertIn(date(2013, 6, 26), holidays) # independence day self.assertIn(date(2013, 8, 15), holidays) # assumption self.assertIn(date(2013, 11, 1), holidays) # all saints self.assertIn(date(2013, 12, 25), holidays) # XMas class IvoryCoastTest(GenericCalendarTest): cal_class = IvoryCoast def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 5, 9), holidays) # ascension self.assertIn(date(2013, 5, 20), holidays) # whit monday self.assertIn(date(2013, 8, 7), holidays) # Independence day self.assertIn(date(2013, 8, 15), holidays) # Assumption self.assertIn(date(2013, 11, 1), holidays) # All saints self.assertIn(date(2013, 11, 15), holidays) # National peace day self.assertIn(date(2013, 12, 25), holidays) # XMas # Muslim days self.assertIn(date(2013, 1, 25), holidays) # Mawlid al-Nabi # Laylat al-Qadr is not computable # self.assertIn(date(2013, 8, 3), holidays) self.assertIn(date(2013, 8, 8), holidays) # End of ramadan self.assertIn(date(2013, 10, 15), holidays) # Feast of sacrifice class SaoTomeAndPrincipeTest(GenericCalendarTest): cal_class = SaoTomeAndPrincipe def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 2, 3), holidays) # Martyrs' day self.assertIn(date(2013, 5, 1), holidays) # Labour Day self.assertIn(date(2013, 7, 12), holidays) # Independence Day self.assertIn(date(2013, 9, 6), holidays) # Armed Forces Day self.assertIn(date(2013, 9, 30), holidays) # Agricultural Reform Day self.assertIn(date(2013, 11, 1), holidays) # All saints self.assertIn(date(2013, 12, 21), holidays) # São Tomé Day self.assertIn(date(2013, 12, 25), holidays) # XMas class AngolaTest(GenericCalendarTest): cal_class = Angola def test_year_2018(self): holidays = self.cal.holidays_set(2018) # Dia de Ano Novo – 1 de Janeiro self.assertIn(date(2018, 1, 1), holidays) # Ano Novo # Dia do Inicio da Luta Armada – 4 de Fevereiro self.assertIn(date(2018, 2, 4), holidays) # Dia do Carnaval – 13 de Fevereiro self.assertIn(date(2018, 2, 13), holidays) # Entrudo # Dia Internacional da Mulher – 8 de Março self.assertIn(date(2018, 3, 8), holidays) # Dia da Paz – 4 de Abril self.assertIn(date(2018, 4, 4), holidays) # Dia da Paz # Sexta Feira Santa – 30 de Março self.assertIn(date(2018, 3, 30), holidays) # Sexta-Feira Santa # Páscoa – 01 de Abril self.assertIn(date(2018, 4, 1), holidays) # Domingo de Páscoa # Dia Internacional do Trabalhador – 1 de Maio self.assertIn(date(2018, 5, 1), holidays) # Dia do Trabalhador # Dia do Fundador da Nação e do Herói Nacional – 17 de Setembro self.assertIn(date(2018, 9, 17), holidays) # Dia dos Finados – 2 de Novembro # Dia da Independência Nacional – 11 de Novembro self.assertIn(date(2018, 11, 11), holidays) # Dia do Natal – 25 de Dezembro self.assertIn(date(2018, 12, 25), holidays) # Natal def test_carnaval_label(self): holidays = self.cal.holidays(2018) holidays_dict = dict(holidays) label_carnaval = holidays_dict[date(2018, 2, 13)] self.assertEqual(label_carnaval, "Dia de Carnaval") def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays_dict = dict(holidays) label = holidays_dict[date(2020, 5, 1)] self.assertEqual(label, "Dia Internacional do Trabalhador") class KenyaTest(GenericCalendarTest): cal_class = Kenya def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Year self.assertIn(date(2019, 4, 19), holidays) # Good Friday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday self.assertIn(date(2019, 5, 1), holidays) # Labour Day self.assertIn(date(2019, 6, 1), holidays) # Madaraka Day self.assertIn(date(2019, 6, 5), holidays) # Eid al-Fitr self.assertIn(date(2019, 8, 12), holidays) # Eid al-Adha self.assertIn(date(2019, 10, 10), holidays) # Moi Day (old name) self.assertIn(date(2019, 10, 20), holidays) # Mashujaa Day self.assertIn(date(2019, 10, 21), holidays) # Mashujaa Day shift self.assertIn(date(2019, 12, 12), holidays) # Jamhuri Day self.assertIn(date(2019, 12, 25), holidays) # Christmas Day self.assertIn(date(2019, 12, 26), holidays) # Boxing Day (old name) self.assertIn(date(2019, 12, 31), holidays) # New Years Eve self.assertEqual(len(holidays), 14) def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 2, 11), holidays) # Moi Memorial (as of 2020) self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 24), holidays) # Eid al-Fitr self.assertIn(date(2020, 6, 1), holidays) # Madaraka Day self.assertIn(date(2020, 7, 31), holidays) # Eid al-Adha self.assertIn(date(2020, 10, 10), holidays) # Huduma Day self.assertIn(date(2020, 10, 20), holidays) # Mashujaa Day self.assertIn(date(2020, 12, 12), holidays) # Jamhuri Day self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 26), holidays) # Utamaduni Day self.assertIn(date(2020, 12, 31), holidays) # New Years Eve self.assertEqual(len(holidays), 14) class NigeriaTest(GenericCalendarTest): cal_class = Nigeria def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Year self.assertIn(date(2019, 4, 19), holidays) # Good Friday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday self.assertIn(date(2019, 5, 1), holidays) # Workers Day self.assertIn(date(2019, 6, 5), holidays) # Eid al-Fitr self.assertIn(date(2019, 6, 12), holidays) # Democracy Day self.assertIn(date(2019, 10, 1), holidays) # Independence Day self.assertIn(date(2019, 8, 12), holidays) # Eid al-Adha self.assertIn(date(2019, 12, 25), holidays) # Christmas Day self.assertIn(date(2019, 12, 26), holidays) # Boxing Day def test_year_2000(self): holidays = self.cal.holidays_set(2000) self.assertIn(date(2000, 5, 29), holidays) # Former Democracy Day def test_year_1998(self): holidays = self.cal.holidays_set(1998) self.assertNotIn(date(1998, 5, 29), holidays) # No Democracy Day yet self.assertNotIn(date(1998, 6, 12), holidays) # No Democracy Day yet calendra-7.9.0/calendra/tests/test_america.py000066400000000000000000000762511457013633400212460ustar00rootroot00000000000000from datetime import date from ..america import ( Argentina, Barbados, Chile, Colombia, ElSalvador, Mexico, Panama, Paraguay ) from . import GenericCalendarTest class ArgentinaTest(GenericCalendarTest): cal_class = Argentina def test_holidays_2018(self): holidays = self.cal.holidays_set(2018) # 1. Año Nuevo self.assertIn(date(2018, 1, 1), holidays) # 2. Carnaval self.assertIn(date(2018, 2, 12), holidays) # 3. Carnaval self.assertIn(date(2018, 2, 13), holidays) # 4. Día de la Memoria self.assertIn(date(2018, 3, 24), holidays) # 5. Día del Veterano y de los Caídos en la Guerra de Malvinas self.assertIn(date(2018, 4, 2), holidays) # 6. Viernes Santo self.assertIn(date(2018, 3, 30), holidays) # 7. Día del Trabajador self.assertIn(date(2018, 5, 1), holidays) # 8. Día de la Revolución de Mayo self.assertIn(date(2018, 5, 25), holidays) # 9. Día Paso a la Inmortalidad del General Manuel Belgrano self.assertIn(date(2018, 6, 20), holidays) # 10. Día de la Independencia self.assertIn(date(2018, 7, 9), holidays) # 11. Inmaculada Concepción de María self.assertIn(date(2018, 12, 8), holidays) # 12. Navidad self.assertIn(date(2018, 12, 25), holidays) # variable days # 13. Día Paso a la Inmortalidad del General Martín Miguel de Güemes self.assertIn(date(2018, 6, 17), holidays) # 14. Paso a la Inmortalidad del General José de San Martín self.assertIn(date(2018, 8, 20), holidays) # 15. Día del Respeto a la Diversidad Cultural self.assertIn(date(2018, 10, 15), holidays) # 16. Día de la Soberanía Nacional self.assertIn(date(2018, 11, 19), holidays) def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) self.assertIn(date(2019, 3, 4), holidays) self.assertIn(date(2019, 3, 5), holidays) self.assertIn(date(2019, 3, 24), holidays) self.assertIn(date(2019, 4, 2), holidays) self.assertIn(date(2019, 4, 19), holidays) self.assertIn(date(2019, 5, 1), holidays) self.assertIn(date(2019, 5, 25), holidays) self.assertIn(date(2019, 6, 20), holidays) self.assertIn(date(2019, 7, 9), holidays) self.assertIn(date(2019, 12, 8), holidays) self.assertIn(date(2019, 12, 25), holidays) # variable days self.assertIn(date(2019, 6, 17), holidays) self.assertIn(date(2019, 8, 19), holidays) self.assertIn(date(2019, 10, 14), holidays) self.assertIn(date(2019, 11, 18), holidays) def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) self.assertIn(date(2020, 2, 24), holidays) self.assertIn(date(2020, 2, 25), holidays) self.assertIn(date(2020, 3, 24), holidays) # Special case: Argentina has shifted this holiday due to # Coronavirus lockdown in 2020. self.assertNotIn(date(2020, 4, 2), holidays) self.assertIn(date(2020, 3, 31), holidays) # Back to normal, I hope... self.assertIn(date(2020, 4, 10), holidays) self.assertIn(date(2020, 5, 1), holidays) self.assertIn(date(2020, 5, 25), holidays) self.assertIn(date(2020, 6, 20), holidays) self.assertIn(date(2020, 7, 9), holidays) self.assertIn(date(2020, 12, 8), holidays) self.assertIn(date(2020, 12, 25), holidays) # variable days self.assertIn(date(2020, 6, 15), holidays) self.assertIn(date(2020, 8, 17), holidays) self.assertIn(date(2020, 10, 12), holidays) self.assertIn(date(2020, 11, 23), holidays) def test_holidays_2021(self): # Testing it because June 17th happens on THU (general_guemes_day). holidays = self.cal.holidays_set(2021) # Not happening on June 17 self.assertNotIn(date(2021, 6, 17), holidays) # Happens on the 1st MON after this date. self.assertIn(date(2021, 6, 20), holidays) # Also, Día del Respeto a la Diversidad Cultural is shifted self.assertNotIn(date(2021, 10, 12), holidays) # The day before self.assertIn(date(2021, 10, 11), holidays) def test_dia_malvinas_label(self): _, label = self.cal.get_malvinas_day(2020) self.assertEqual( label, "Día del Veterano y de los Caídos en la Guerra de Malvinas" ) def test_dia_memoria_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) label_memoria = holidays[date(2020, 3, 24)] self.assertEqual( label_memoria, "Día Nacional de la Memoria por la Verdad y la Justicia" ) def test_carnival_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) label_carnival = holidays[date(2020, 2, 25)] self.assertEqual(label_carnival, "Carnival") def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) label = holidays[date(2020, 5, 1)] self.assertEqual(label, "Día del Trabajador") def test_immaculate_conception_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) label = holidays[date(2020, 12, 8)] self.assertEqual(label, "Día de la Inmaculada Concepción de María") class ChileTest(GenericCalendarTest): cal_class = Chile def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 3, 29), holidays) self.assertIn(date(2013, 3, 30), holidays) self.assertIn(date(2013, 5, 1), holidays) self.assertIn(date(2013, 5, 21), holidays) self.assertIn(date(2013, 6, 29), holidays) self.assertIn(date(2013, 7, 16), holidays) self.assertIn(date(2013, 8, 15), holidays) self.assertIn(date(2013, 9, 18), holidays) self.assertIn(date(2013, 9, 19), holidays) self.assertIn(date(2013, 9, 20), holidays) self.assertIn(date(2013, 10, 12), holidays) self.assertIn(date(2013, 10, 31), holidays) self.assertIn(date(2013, 11, 1), holidays) self.assertIn(date(2013, 12, 8), holidays) self.assertIn(date(2013, 12, 25), holidays) self.assertIn(date(2013, 12, 31), holidays) def test_holidays_2021(self): holidays = self.cal.holidays_set(2021) # Año Nuevo self.assertIn(date(2021, 1, 1), holidays) # Viernes Santo self.assertIn(date(2021, 4, 2), holidays) # Sábado Santo self.assertIn(date(2021, 4, 3), holidays) # Día Nacional del Trabajo self.assertIn(date(2021, 5, 1), holidays) # Día de las Glorias Navales self.assertIn(date(2021, 5, 21), holidays) # día nacional de los pueblos indígenas (June solstice) self.assertIn(date(2021, 6, 21), holidays) # San Pedro y San Pablo self.assertIn(date(2021, 6, 28), holidays) # Día de la Virgen del Carmen self.assertIn(date(2021, 7, 16), holidays) # Asunción de la Virgen self.assertIn(date(2021, 8, 15), holidays) # Additional Holiday self.assertIn(date(2021, 9, 17), holidays) # Independencia Nacional self.assertIn(date(2021, 9, 18), holidays) # Día de las Glorias del Ejército self.assertIn(date(2021, 9, 19), holidays) # Encuentro de Dos Mundos self.assertIn(date(2021, 10, 11), holidays) # Día de las Iglesias Evangélicas y Protestantes self.assertIn(date(2021, 10, 31), holidays) # Día de Todos los Santos self.assertIn(date(2021, 11, 1), holidays) # Inmaculada Concepción self.assertIn(date(2021, 12, 8), holidays) # Navidad self.assertIn(date(2021, 12, 25), holidays) # Feriado Bancario self.assertIn(date(2021, 12, 31), holidays) def test_indigenous_people_day(self): # Testing because variable nature of June solstice # approved in 2021 holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 6, 21), holidays) self.assertNotIn(date(2020, 6, 20), holidays) # fixed day in 2021 holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 6, 21), holidays) # solstice 2022 holidays = self.cal.holidays_set(2022) self.assertIn(date(2022, 6, 21), holidays) # solstice 2023 holidays = self.cal.holidays_set(2023) self.assertIn(date(2023, 6, 21), holidays) # solstice 2023 holidays = self.cal.holidays_set(2024) self.assertIn(date(2024, 6, 20), holidays) def test_reformation_day(self): holidays = self.cal.holidays_set(2012) self.assertNotIn(date(2012, 10, 31), holidays) self.assertIn(date(2012, 11, 2), holidays) holidays = self.cal.holidays_set(2017) self.assertNotIn(date(2017, 10, 31), holidays) self.assertIn(date(2017, 10, 27), holidays) def test_national_bridge_days(self): # MON TUE holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 9, 18), holidays) self.assertIn(date(2017, 9, 19), holidays) # TUE WED holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 9, 17), holidays) self.assertIn(date(2018, 9, 18), holidays) self.assertIn(date(2018, 9, 19), holidays) self.assertNotIn(date(2018, 9, 20), holidays) # WED THU holidays = self.cal.holidays_set(2019) self.assertNotIn(date(2019, 9, 17), holidays) self.assertIn(date(2019, 9, 18), holidays) self.assertIn(date(2019, 9, 19), holidays) self.assertIn(date(2019, 9, 20), holidays) # THU FRI holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 9, 18), holidays) self.assertIn(date(2020, 9, 19), holidays) # FRI SAT holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 9, 17), holidays) self.assertIn(date(2015, 9, 18), holidays) self.assertIn(date(2015, 9, 19), holidays) # SUN MON holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 9, 18), holidays) self.assertIn(date(2016, 9, 19), holidays) self.assertNotIn(date(2016, 9, 20), holidays) # SAT SUN for additional day holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 9, 17), holidays) self.assertIn(date(2021, 9, 18), holidays) self.assertIn(date(2021, 9, 19), holidays) def test_columbus_day(self): # MON holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 10, 12), holidays) # TUE holidays = self.cal.holidays_set(2021) self.assertNotIn(date(2021, 10, 12), holidays) self.assertIn(date(2021, 10, 11), holidays) # WED holidays = self.cal.holidays_set(2016) self.assertNotIn(date(2016, 10, 12), holidays) self.assertIn(date(2016, 10, 10), holidays) # THU holidays = self.cal.holidays_set(2017) self.assertNotIn(date(2017, 10, 12), holidays) self.assertIn(date(2017, 10, 9), holidays) # FRI holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 10, 12), holidays) self.assertIn(date(2018, 10, 15), holidays) def test_st_peter_and_st_paul_day(self): # MON holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 6, 29), holidays) # TUE holidays = self.cal.holidays_set(2021) self.assertNotIn(date(2021, 6, 29), holidays) self.assertIn(date(2021, 6, 28), holidays) # WED holidays = self.cal.holidays_set(2016) self.assertNotIn(date(2016, 6, 29), holidays) self.assertIn(date(2016, 6, 27), holidays) # THU holidays = self.cal.holidays_set(2017) self.assertNotIn(date(2017, 6, 29), holidays) self.assertIn(date(2017, 6, 26), holidays) # FRI holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 6, 29), holidays) self.assertIn(date(2018, 7, 2), holidays) class ColombiaTest(GenericCalendarTest): cal_class = Colombia def test_holidays_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # New year self.assertIn(date(2015, 1, 12), holidays) # Epiphany (shifted) self.assertIn(date(2015, 3, 23), holidays) # Saint Joseph self.assertIn(date(2015, 3, 29), holidays) # Palm Sunday self.assertIn(date(2015, 4, 2), holidays) # Holy Thursday self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 4, 5), holidays) # Easter (SUN) self.assertIn(date(2015, 5, 1), holidays) # Labour Day self.assertIn(date(2015, 5, 18), holidays) # Ascension (shifted) self.assertIn(date(2015, 6, 8), holidays) # Corpus Christi self.assertIn(date(2015, 6, 15), holidays) # Sacred Heart self.assertIn(date(2015, 6, 29), holidays) # St Peter & St Paul self.assertIn(date(2015, 7, 20), holidays) # Independance Day self.assertIn(date(2015, 8, 7), holidays) # Boyacá battle self.assertIn(date(2015, 8, 17), holidays) # Assumption (shifted) self.assertIn(date(2015, 10, 12), holidays) # Day of the Races self.assertIn(date(2015, 11, 2), holidays) # All Saints (shifted) self.assertIn(date(2015, 11, 16), holidays) # Cartagena independence self.assertIn(date(2015, 12, 8), holidays) # Immaculate Conception self.assertIn(date(2015, 12, 25), holidays) # XMas self.assertEqual(len(holidays), 20) def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New year self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 23), holidays) # Saint Joseph self.assertIn(date(2020, 4, 5), holidays) # Palm Sunday self.assertIn(date(2020, 4, 9), holidays) # Holy Thursday self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 12), holidays) # Easter (SUN) self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 25), holidays) # Ascension (shifted) self.assertIn(date(2020, 6, 15), holidays) # Corpus Christi self.assertIn(date(2020, 6, 22), holidays) # Sacred Heart self.assertIn(date(2020, 6, 29), holidays) # St Peter & St Paul self.assertIn(date(2020, 7, 20), holidays) # Independance Day self.assertIn(date(2020, 8, 7), holidays) # Boyacá battle self.assertIn(date(2020, 8, 17), holidays) # Assumption (shifted) self.assertIn(date(2020, 10, 12), holidays) # Day of the Races self.assertIn(date(2020, 11, 2), holidays) # All Saints (shifted) self.assertIn(date(2020, 11, 16), holidays) # Cartagena independence self.assertIn(date(2020, 12, 8), holidays) # Immaculate Conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertEqual(len(holidays), 20) def test_epiphany_monday(self): # In 2020, Epiphany falls on MON epiphany_2020 = self.cal.get_epiphany(2020) self.assertEqual(epiphany_2020, date(2020, 1, 6)) # In 2021, it does not, so it's shifted to the next MON epiphany_2021 = self.cal.get_epiphany(2021) self.assertEqual(epiphany_2021, date(2021, 1, 11)) def test_saint_peter_and_saint_paul_monday(self): # In 2020, Saint Peter and Saint Paul falls on MON st_peter_paul_2020 = self.cal.get_saint_peter_and_saint_paul(2020) self.assertEqual(st_peter_paul_2020, date(2020, 6, 29)) # In 2021, it does not, so it's shifted to the next MON st_peter_paul_2021 = self.cal.get_saint_peter_and_saint_paul(2021) self.assertEqual(st_peter_paul_2021, date(2021, 7, 5)) def test_assumption_monday(self): # In 2021, Assumption falls on SUN, so it's shifted to MON assumption_2021 = self.cal.get_assumption(2021) self.assertEqual(assumption_2021, date(2021, 8, 16)) # In 2022, Assumption falls on MON assumption_2022 = self.cal.get_assumption(2022) self.assertEqual(assumption_2022, date(2022, 8, 15)) def test_day_of_the_races_monday(self): # In 2020, Day of the races and hispanity falls on MON day_races_2020 = self.cal.get_day_of_the_races(2020) self.assertEqual(day_races_2020, date(2020, 10, 12)) # In 2021, It does not, so it's shifted to the next MON day_races_2021 = self.cal.get_day_of_the_races(2021) self.assertEqual(day_races_2021, date(2021, 10, 18)) def test_all_saints_monday(self): # In 2021, The All Saints falls on MON all_saints_2021 = self.cal.get_all_saints(2021) self.assertEqual(all_saints_2021, date(2021, 11, 1)) # In 2022, It does not, so it's shifted to the next MON all_saints_2022 = self.cal.get_all_saints(2022) self.assertEqual(all_saints_2022, date(2022, 11, 7)) def test_cartagena_independence_monday(self): # In 2019, The Cartagena Independance falls on MON cartagena_2019 = self.cal.get_cartagena_independence(2019) self.assertEqual(cartagena_2019, date(2019, 11, 11)) # In 2020, It does not, so it's shifted to the next MON cartagena_2020 = self.cal.get_cartagena_independence(2020) self.assertEqual(cartagena_2020, date(2020, 11, 16)) class MexicoTest(GenericCalendarTest): cal_class = Mexico def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 2, 4), holidays) # Constitution day self.assertIn(date(2013, 3, 18), holidays) # Benito Juárez's birthday self.assertIn(date(2013, 5, 1), holidays) # Labour day self.assertIn(date(2013, 9, 16), holidays) # Independence day self.assertIn(date(2013, 11, 18), holidays) # Revolution day self.assertIn(date(2013, 12, 25), holidays) # XMas def test_shift_to_monday(self): observed = self.cal.observed_holidays(2017) # New year on Sunday -> shift assert date(2017, 1, 2) in observed observed = self.cal.observed_holidays(2016) # XMas on sunday -> shift to monday assert date(2016, 12, 26) in observed # Same for Labour day assert date(2016, 5, 2) in observed def test_shift_to_friday(self): observed = self.cal.observed_holidays(2021) | self.cal.observed_holidays(2022) # January 1st 2022 is a saturday, so we shift to friday assert date(2021, 12, 31) in observed # Same for Labour day assert date(2021, 4, 30) in observed observed = self.cal.observed_holidays(2021) # December 25th, 2022 is a saturday, so we shift to friday assert date(2021, 12, 24) in observed class PanamaTest(GenericCalendarTest): cal_class = Panama def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 1, 9), holidays) # Martyrs day self.assertIn(date(2013, 2, 12), holidays) # carnival tuesday self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 3, 30), holidays) # easter saturday self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 11, 3), holidays) # independence day self.assertIn(date(2013, 11, 5), holidays) # colon day # Shout in Villa de los Santos self.assertIn(date(2013, 11, 10), holidays) self.assertIn(date(2013, 11, 28), holidays) # Independence from spain self.assertIn(date(2013, 12, 8), holidays) # mother day self.assertIn(date(2013, 12, 25), holidays) # XMas class ParaguayTest(GenericCalendarTest): cal_class = Paraguay def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) self.assertIn(date(2019, 3, 1), holidays) # Heroes day self.assertIn(date(2019, 4, 18), holidays) # Maundy thursday self.assertIn(date(2019, 4, 19), holidays) # Good friday self.assertIn(date(2019, 5, 1), holidays) # Labour day self.assertIn(date(2019, 5, 14), holidays) # Independance day self.assertIn(date(2019, 6, 12), holidays) # Chaco Armistice Day self.assertIn(date(2019, 8, 15), holidays) # Founding of Asunción self.assertIn(date(2019, 9, 29), holidays) # Boqueron Battle Victory self.assertIn(date(2019, 12, 8), holidays) # Virgin of Caacupe self.assertIn(date(2019, 12, 25), holidays) # XMas def test_holidays_2017(self): holidays = self.cal.holidays_set(2017) # In 2017, Heroes day has been moved to February 27th self.assertNotIn(date(2017, 3, 1), holidays) self.assertIn(date(2017, 2, 27), holidays) # Fundation of Asunción day: moved to August 14 for 2017 self.assertNotIn(date(2017, 8, 15), holidays) self.assertIn(date(2017, 8, 14), holidays) # Boqueron Battle Victory Day: moved to October 2nd for 2017 self.assertNotIn(date(2017, 9, 29), holidays) self.assertIn(date(2017, 10, 2), holidays) def test_immaculate_conception_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) label = holidays[date(2020, 12, 8)] self.assertEqual(label, "Virgin of Caacupé Day") class BarbadosTest(GenericCalendarTest): cal_class = Barbados def test_holidays_2009(self): holidays = self.cal.holidays_set(2009) self.assertIn(date(2009, 1, 1), holidays) self.assertIn(date(2009, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2009, 4, 10), holidays) # Good Friday self.assertIn(date(2009, 4, 12), holidays) # Easter Sunday self.assertIn(date(2009, 4, 13), holidays) # Easter Monday self.assertIn(date(2009, 4, 28), holidays) # National Heroes Day self.assertIn(date(2009, 5, 1), holidays) # Labour Day self.assertIn(date(2009, 6, 1), holidays) # Whit Monday self.assertIn(date(2009, 8, 1), holidays) # Emancipation Day self.assertIn(date(2009, 8, 3), holidays) # Kabooment Day self.assertIn(date(2009, 11, 30), holidays) # Independant Day self.assertIn(date(2009, 12, 25), holidays) # Christmas Day self.assertIn(date(2009, 12, 26), holidays) # Boxing Day def test_holidays_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) self.assertIn(date(2016, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2016, 3, 25), holidays) # Good Friday self.assertIn(date(2016, 3, 28), holidays) # Easter Monday self.assertIn(date(2016, 4, 28), holidays) # National Heroes Day self.assertIn(date(2016, 5, 2), holidays) # Labour Day self.assertIn(date(2016, 5, 16), holidays) # Whit Monday self.assertIn(date(2016, 8, 1), holidays) # Kabooment Day self.assertIn(date(2016, 8, 2), holidays) # Emancipation Day self.assertIn(date(2016, 11, 30), holidays) # Independant Day self.assertIn(date(2016, 12, 25), holidays) # Christmas Day self.assertIn(date(2016, 12, 26), holidays) # Boxing Day self.assertIn(date(2016, 12, 27), holidays) # Public Holiday def test_holidays_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) self.assertIn(date(2018, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2018, 1, 22), holidays) # Errol Barrow Day (shift) self.assertIn(date(2018, 3, 30), holidays) # Good Friday self.assertIn(date(2018, 4, 1), holidays) # Easter Sunday self.assertIn(date(2018, 4, 2), holidays) # Easter Monday self.assertIn(date(2018, 4, 28), holidays) # National Heroes Day self.assertIn(date(2018, 5, 1), holidays) # Labour Day self.assertIn(date(2018, 5, 21), holidays) # Whit Monday self.assertIn(date(2018, 8, 1), holidays) # Emancipation Day self.assertIn(date(2018, 8, 6), holidays) # Kabooment Day self.assertIn(date(2018, 11, 30), holidays) # Independant Day self.assertIn(date(2018, 12, 25), holidays) # Christmas Day self.assertIn(date(2018, 12, 26), holidays) # Boxing Day def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) self.assertIn(date(2019, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2019, 4, 19), holidays) # Good Friday self.assertIn(date(2019, 4, 21), holidays) # Easter Sunday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday # National Heroes Day & shift self.assertIn(date(2019, 4, 28), holidays) self.assertIn(date(2019, 4, 29), holidays) # shft'd self.assertIn(date(2019, 5, 1), holidays) # Labour Day self.assertIn(date(2019, 6, 10), holidays) # Whit Monday self.assertIn(date(2019, 8, 1), holidays) # Emancipation Day self.assertIn(date(2019, 8, 5), holidays) # Kabooment Day self.assertIn(date(2019, 11, 30), holidays) # Independant Day self.assertIn(date(2019, 12, 25), holidays) # Christmas Day self.assertIn(date(2019, 12, 26), holidays) # Boxing Day def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) self.assertIn(date(2020, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday # National Heroes Day & shift self.assertIn(date(2020, 4, 28), holidays) self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Emancipation Day self.assertIn(date(2020, 8, 3), holidays) # Kabooment Day self.assertIn(date(2020, 11, 30), holidays) # Independant Day self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 26), holidays) # Boxing Day def test_holidays_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year's Day self.assertIn(date(2021, 1, 4), holidays) # Public Holiday self.assertIn(date(2021, 1, 5), holidays) # Public Holiday self.assertIn(date(2021, 1, 21), holidays) # Errol Barrow Day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 4, 28), holidays) # National Heroes Day self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 2), holidays) # Kabooment Day self.assertIn(date(2021, 8, 3), holidays) # Emancipation Day self.assertIn(date(2021, 11, 30), holidays) # Independant Day self.assertIn(date(2021, 12, 25), holidays) # Christmas Day self.assertIn(date(2021, 12, 27), holidays) # Boxing Day class ElSalvadorTest(GenericCalendarTest): cal_class = ElSalvador def test_holidays_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New Year's Day self.assertIn(date(2018, 3, 29), holidays) # Maundy Thursday self.assertIn(date(2018, 3, 30), holidays) # Good Friday self.assertIn(date(2018, 3, 31), holidays) # Holy Saturday self.assertIn(date(2018, 5, 1), holidays) # Labor Day self.assertIn(date(2018, 5, 10), holidays) # Mothers' Day self.assertIn(date(2018, 6, 17), holidays) # Fathers' Day # Celebrations of San Salvador self.assertIn(date(2018, 8, 6), holidays) self.assertIn(date(2018, 9, 15), holidays) # Independence Day self.assertIn(date(2018, 11, 2), holidays) # All Saints Day self.assertIn(date(2018, 12, 25), holidays) # XMas def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Year's Day self.assertIn(date(2019, 4, 18), holidays) # Maundy Thursday self.assertIn(date(2019, 4, 19), holidays) # Good Friday self.assertIn(date(2019, 4, 20), holidays) # Holy Saturday self.assertIn(date(2019, 5, 1), holidays) # Labor Day self.assertIn(date(2019, 5, 10), holidays) # Mothers' Day self.assertIn(date(2019, 6, 17), holidays) # Fathers' Day # Celebrations of San Salvador self.assertIn(date(2019, 8, 6), holidays) self.assertIn(date(2019, 9, 15), holidays) # Independence Day self.assertIn(date(2019, 11, 2), holidays) # All Saints Day self.assertIn(date(2019, 12, 25), holidays) # XMas def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year's Day self.assertIn(date(2020, 4, 9), holidays) # Maundy Thursday self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 11), holidays) # Holy Saturday self.assertIn(date(2020, 5, 1), holidays) # Labor Day self.assertIn(date(2020, 5, 10), holidays) # Mothers' Day self.assertIn(date(2020, 6, 17), holidays) # Fathers' Day # Celebrations of San Salvador self.assertIn(date(2020, 8, 6), holidays) self.assertIn(date(2020, 9, 15), holidays) # Independence Day self.assertIn(date(2020, 11, 2), holidays) # All Saints Day self.assertIn(date(2020, 12, 25), holidays) # XMas def test_holidays_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year's Day self.assertIn(date(2021, 4, 2), holidays) # Maundy Thursday self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 3), holidays) # Holy Saturday self.assertIn(date(2021, 5, 1), holidays) # Labor Day self.assertIn(date(2021, 5, 10), holidays) # Mothers' Day self.assertIn(date(2021, 6, 17), holidays) # Fathers' Day # Celebrations of San Salvador self.assertIn(date(2021, 8, 6), holidays) self.assertIn(date(2021, 9, 15), holidays) # Independence Day self.assertIn(date(2021, 11, 2), holidays) # All Saints Day self.assertIn(date(2021, 12, 25), holidays) # XMas calendra-7.9.0/calendra/tests/test_asia.py000066400000000000000000001451411457013633400205550ustar00rootroot00000000000000from unittest.mock import patch from datetime import date import time from . import GenericCalendarTest from ..asia import ( HongKong, HongKongBank, Japan, JapanBank, Qatar, Singapore, SouthKorea, Taiwan, Malaysia, China, Israel, Philippines, Kazakhstan ) from ..asia.china import holidays as china_holidays from ..exceptions import CalendarError class ChinaTest(GenericCalendarTest): cal_class = China def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New year self.assertIn(date(2018, 2, 15), holidays) # Spring Festival self.assertIn(date(2018, 2, 21), holidays) # Spring Festival self.assertIn(date(2018, 10, 1), holidays) # National Day self.assertIn(date(2018, 10, 7), holidays) # National Day # Variable days self.assertIn(date(2018, 4, 5), holidays) # Ching Ming Festival self.assertIn(date(2018, 4, 7), holidays) # Ching Ming Festival self.assertIn(date(2018, 4, 29), holidays) # Labour Day Holiday self.assertIn(date(2018, 5, 1), holidays) # Labour Day Holiday self.assertIn(date(2018, 6, 18), holidays) # Dragon Boat Festival self.assertIn(date(2018, 9, 24), holidays) # Mid-Autumn Festival self.assertIn(date(2018, 12, 30), holidays) # New year self.assertIn(date(2018, 12, 31), holidays) # New year def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertNotIn(date(2019, 4, 28), holidays) # Labour Day Shift self.assertIn(date(2019, 5, 1), holidays) # Labour Day Holiday self.assertIn(date(2019, 5, 2), holidays) # Labour Day Holiday self.assertIn(date(2019, 5, 3), holidays) # Labour Day Holiday self.assertNotIn(date(2019, 5, 5), holidays) # Labour Day Shift def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 25), holidays) # Spring Festival self.assertIn(date(2020, 4, 4), holidays) # Ching Ming Festival self.assertIn(date(2020, 4, 6), holidays) # Ching Ming Festival self.assertIn(date(2020, 5, 1), holidays) # Labour Day Holiday self.assertIn(date(2020, 5, 5), holidays) # Labour Day Holiday self.assertIn(date(2020, 6, 25), holidays) # Dragon Boat Festival self.assertIn(date(2020, 6, 27), holidays) # Dragon Boat Festival self.assertIn(date(2020, 10, 1), holidays) # National Day self.assertIn(date(2020, 10, 8), holidays) # National Day self.assertNotIn(date(2020, 1, 19), holidays) # Spring Festival Shift self.assertNotIn(date(2020, 2, 1), holidays) # Spring Festival Shift self.assertNotIn(date(2020, 4, 26), holidays) # Labour Day Shift self.assertNotIn(date(2020, 5, 9), holidays) # Labour Day Shift self.assertNotIn(date(2020, 6, 28), holidays) # Dragon Boat Shift self.assertNotIn(date(2020, 9, 27), holidays) # National Day Shift self.assertNotIn(date(2020, 10, 10), holidays) # National Day Shift def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year self.assertIn(date(2021, 2, 11), holidays) # Spring Festival self.assertIn(date(2021, 2, 17), holidays) # Spring Festival self.assertIn(date(2021, 4, 3), holidays) # Ching Ming Festival self.assertIn(date(2021, 4, 5), holidays) # Ching Ming Festival self.assertIn(date(2021, 5, 1), holidays) # Labour Day Holiday self.assertIn(date(2021, 5, 5), holidays) # Labour Day Holiday self.assertIn(date(2021, 6, 12), holidays) # Dragon Boat Festival self.assertIn(date(2021, 6, 14), holidays) # Dragon Boat Festival self.assertIn(date(2021, 9, 19), holidays) # Mid-Autumn Festival self.assertIn(date(2021, 9, 21), holidays) # Mid-Autumn Festival self.assertIn(date(2021, 10, 1), holidays) # National Day self.assertIn(date(2021, 10, 7), holidays) # National Day self.assertNotIn(date(2021, 2, 7), holidays) # Spring Festival Shift self.assertNotIn(date(2021, 2, 20), holidays) # Spring Festival Shift self.assertNotIn(date(2021, 4, 25), holidays) # Labour Day Shift self.assertNotIn(date(2021, 5, 8), holidays) # Labour Day Shift self.assertNotIn(date(2021, 9, 18), holidays) # Mid-Autumn Shift self.assertNotIn(date(2021, 9, 26), holidays) # National Day Shift self.assertNotIn(date(2021, 10, 9), holidays) # National Day Shift def test_year_2022(self): holidays = self.cal.holidays_set(2022) self.assertIn(date(2022, 1, 1), holidays) # New Year self.assertIn(date(2022, 1, 3), holidays) # New Year self.assertIn(date(2022, 1, 31), holidays) # Spring Festival self.assertIn(date(2022, 2, 6), holidays) # Spring Festival self.assertIn(date(2022, 4, 3), holidays) # Ching Ming Festival self.assertIn(date(2022, 4, 5), holidays) # Ching Ming Festival self.assertIn(date(2022, 4, 30), holidays) # Labour Day Holiday self.assertIn(date(2022, 5, 4), holidays) # Labour Day Holiday self.assertIn(date(2022, 6, 3), holidays) # Dragon Boat Festival self.assertIn(date(2022, 6, 5), holidays) # Dragon Boat Festival self.assertIn(date(2022, 9, 10), holidays) # Mid-Autumn Festival self.assertIn(date(2022, 9, 12), holidays) # Mid-Autumn Festival self.assertIn(date(2022, 10, 1), holidays) # National Day self.assertIn(date(2022, 10, 7), holidays) # National Day self.assertNotIn(date(2022, 1, 29), holidays) # Spring Festival Shift self.assertNotIn(date(2022, 1, 30), holidays) # Spring Festival Shift # Ching Ming Festival Shift self.assertNotIn(date(2022, 4, 2), holidays) self.assertNotIn(date(2022, 4, 24), holidays) # Labour Day Shift self.assertNotIn(date(2022, 5, 7), holidays) # Labour Day Shift self.assertNotIn(date(2022, 10, 8), holidays) # National Day Shift self.assertNotIn(date(2022, 10, 9), holidays) # National Day Shift def test_year_2023(self): holidays = self.cal.holidays_set(2023) self.assertIn(date(2023, 1, 2), holidays) # New Year self.assertIn(date(2023, 1, 21), holidays) # Spring Festival self.assertIn(date(2023, 1, 27), holidays) # Spring Festival self.assertIn(date(2023, 4, 5), holidays) # Ching Ming Festival self.assertIn(date(2023, 4, 29), holidays) # Labour Day Holiday self.assertIn(date(2023, 5, 3), holidays) # Labour Day Holiday self.assertIn(date(2023, 6, 22), holidays) # Dragon Boat Festival self.assertIn(date(2023, 6, 24), holidays) # Dragon Boat Festival self.assertIn(date(2023, 9, 29), holidays) # Mid-Autumn Festival self.assertIn(date(2023, 9, 30), holidays) # National Day self.assertIn(date(2023, 10, 6), holidays) # National Day self.assertNotIn(date(2023, 1, 28), holidays) # Spring Festival Shift self.assertNotIn(date(2023, 1, 29), holidays) # Spring Festival Shift self.assertNotIn(date(2023, 4, 23), holidays) # Labour Day Shift self.assertNotIn(date(2023, 5, 6), holidays) # Labour Day Shift self.assertNotIn(date(2023, 10, 7), holidays) # National Day Shift self.assertNotIn(date(2023, 10, 8), holidays) # National Day Shift def test_year_2024(self): holidays = self.cal.holidays_set(2024) self.assertIn(date(2024, 1, 1), holidays) # New Year for i in range(10, 18): self.assertIn(date(2024, 2, i), holidays) # Spring Festival self.assertIn(date(2024, 4, 4), holidays) # Ching Ming Festival self.assertIn(date(2024, 4, 5), holidays) # Ching Ming Festival self.assertIn(date(2024, 4, 6), holidays) # Ching Ming Festival for i in range(1, 6): self.assertIn(date(2024, 5, i), holidays) # Labour Day Holiday self.assertIn(date(2024, 6, 8), holidays) # Dragon Boat Festival self.assertIn(date(2024, 6, 9), holidays) # Dragon Boat Festival self.assertIn(date(2024, 6, 10), holidays) # Dragon Boat Festival self.assertIn(date(2024, 9, 15), holidays) # Mid-Autumn Festival self.assertIn(date(2024, 9, 16), holidays) # Mid-Autumn Festival self.assertIn(date(2024, 9, 17), holidays) # Mid-Autumn Festival for i in range(1, 8): self.assertIn(date(2024, 10, i), holidays) # National Day self.assertNotIn(date(2024, 2, 4), holidays) # Spring Festival Shift self.assertNotIn(date(2024, 2, 9), holidays) # Spring Festival Shift self.assertNotIn(date(2024, 2, 18), holidays) # Spring Festival Shift # Ching Ming Festival Shift self.assertNotIn(date(2024, 4, 7), holidays) self.assertNotIn(date(2024, 4, 28), holidays) # Labour Day Shift self.assertNotIn(date(2024, 5, 11), holidays) # Labour Day Shift # Mid-Autumn Festival Shift self.assertNotIn(date(2024, 9, 14), holidays) self.assertNotIn(date(2024, 9, 29), holidays) # National Day Shift self.assertNotIn(date(2024, 10, 12), holidays) # National Day Shift def test_missing_holiday_year(self): save_2018 = china_holidays[2018] del china_holidays[2018] with self.assertRaises(CalendarError): self.cal.holidays_set(2018) china_holidays[2018] = save_2018 def test_warning(self): year = date.today().year with patch('warnings.warn') as patched: self.cal.get_calendar_holidays(year) patched.assert_called_with( 'Support years 2018-2024 currently, need update every year.' ) def test_is_working_day(self): # It's a SAT, but it's a working day this year self.assertTrue(self.cal.is_working_day(date(2019, 2, 2))) # It's a SUN, but it's a working day this year self.assertTrue(self.cal.is_working_day(date(2019, 2, 3))) def test_add_working_days(self): # Normally, February 1st + 1 working day would be on February 4th # Because 2nd and 3rd are on SAT and SUN. self.assertEqual( self.cal.add_working_days(date(2019, 2, 1), 1), date(2019, 2, 2) ) def test_sub_working_days(self): # Normally, February 4th - 1 working day would be on February 1st # Because 2nd and 3rd are on SAT and SUN. self.assertEqual( self.cal.sub_working_days(date(2019, 2, 4), 1), date(2019, 2, 3) ) class HongKongTest(GenericCalendarTest): cal_class = HongKong def test_year_2010(self): # Interesting because Christmas fell on a Saturday and CNY fell # on a Sunday, so didn't roll, and Ching Ming was on the same day # as Easter Monday # https://www.gov.hk/en/about/abouthk/holiday/2010.htm holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 1, 1), holidays) # New Year self.assertIn(date(2010, 2, 13), holidays) # Chinese new year (shift) self.assertIn(date(2010, 2, 15), holidays) # Chinese new year self.assertIn(date(2010, 2, 16), holidays) # Chinese new year self.assertNotIn(date(2010, 2, 17), holidays) # Not Chinese new year self.assertIn(date(2010, 4, 2), holidays) # Good Friday self.assertIn(date(2010, 4, 3), holidays) # Day after Good Friday self.assertIn(date(2010, 4, 5), holidays) # Easter Monday self.assertIn(date(2010, 4, 6), holidays) # Ching Ming (shifted) self.assertIn(date(2010, 5, 1), holidays) # Labour Day self.assertIn(date(2010, 5, 21), holidays) # Buddha's Birthday self.assertIn(date(2010, 6, 16), holidays) # Tuen Ng Festival self.assertIn(date(2010, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2010, 9, 23), holidays) # Day after Mid-Autumn self.assertIn(date(2010, 10, 1), holidays) # National Day self.assertIn(date(2010, 10, 16), holidays) # Chung Yeung Festival self.assertIn(date(2010, 12, 25), holidays) # Christmas Day observed = self.cal.observed_holidays(2010) self.assertIn(date(2010, 12, 27), observed) # Boxing Day (shifted) def test_year_2013(self): # https://www.gov.hk/en/about/abouthk/holiday/2013.htm holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year self.assertIn(date(2013, 2, 11), holidays) # Chinese new year self.assertIn(date(2013, 2, 12), holidays) # Chinese new year self.assertIn(date(2013, 2, 13), holidays) # Chinese new year self.assertIn(date(2013, 3, 29), holidays) # Good Friday self.assertIn(date(2013, 3, 30), holidays) # Day after Good Friday self.assertIn(date(2013, 4, 1), holidays) # Easter Monday self.assertIn(date(2013, 4, 4), holidays) # Ching Ming self.assertIn(date(2013, 5, 1), holidays) # Labour Day self.assertIn(date(2013, 5, 17), holidays) # Buddha's Birthday self.assertIn(date(2013, 6, 12), holidays) # Tuen Ng Festival self.assertIn(date(2013, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2013, 9, 20), holidays) # Day after Mid-Autumn self.assertIn(date(2013, 10, 1), holidays) # National Day observed = self.cal.observed_holidays(2013) self.assertIn(date(2013, 10, 14), observed) # Chung Yeung Festival self.assertIn(date(2013, 12, 25), holidays) # Christmas Day self.assertIn(date(2013, 12, 26), holidays) # Boxing Day def test_year_2016(self): # https://www.gov.hk/en/about/abouthk/holiday/2016.htm holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Year self.assertIn(date(2016, 2, 8), holidays) # Chinese new year self.assertIn(date(2016, 2, 9), holidays) # Chinese new year self.assertIn(date(2016, 2, 10), holidays) # Chinese new year self.assertIn(date(2016, 3, 25), holidays) # Good Friday self.assertIn(date(2016, 3, 26), holidays) # Day after Good Friday self.assertIn(date(2016, 3, 28), holidays) # Easter Monday self.assertIn(date(2016, 4, 4), holidays) # Ching Ming self.assertIn(date(2016, 5, 1), holidays) # Labour Day (SUN) observed = self.cal.observed_holidays(2016) self.assertIn(date(2016, 5, 2), observed) # Labour Day (shifted) self.assertIn(date(2016, 5, 14), holidays) # Buddha's Birthday self.assertIn(date(2016, 6, 9), holidays) # Tuen Ng Festival self.assertIn(date(2016, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2016, 9, 16), holidays) # Day after Mid-Autumn self.assertIn(date(2016, 10, 1), holidays) # National Day self.assertIn(date(2016, 10, 10), observed) # Chung Yeung Festival self.assertIn(date(2016, 12, 25), holidays) # Christmas Day self.assertIn(date(2016, 12, 26), holidays) # Christmas + Boxing Day self.assertIn(date(2016, 12, 27), holidays) # Second weekday def test_year_2017(self): # https://www.gov.hk/en/about/abouthk/holiday/2017.htm holidays = self.cal.holidays_set(2017) observed = self.cal.observed_holidays(2017) self.assertIn(date(2017, 1, 2), observed) # New Year (shifted) self.assertIn(date(2017, 1, 28), holidays) # Chinese new year self.assertIn(date(2017, 1, 30), holidays) # Chinese new year self.assertIn(date(2017, 1, 31), holidays) # Chinese new year self.assertIn(date(2017, 4, 4), holidays) # Ching Ming self.assertIn(date(2017, 4, 14), holidays) # Good Friday self.assertIn(date(2017, 4, 15), holidays) # Day after Good Friday self.assertIn(date(2017, 4, 17), holidays) # Easter Monday self.assertIn(date(2017, 5, 1), holidays) # Labour Day self.assertIn(date(2017, 5, 3), holidays) # Buddha's Birthday self.assertIn(date(2017, 5, 30), holidays) # Tuen Ng Festival self.assertIn(date(2017, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2017, 10, 2), observed) # National Day (shifted) self.assertIn(date(2017, 10, 5), holidays) # Day after Mid-Autumn self.assertIn(date(2017, 10, 28), holidays) # Chung Yeung Festival self.assertIn(date(2017, 12, 25), holidays) # Christmas Day self.assertIn(date(2017, 12, 26), holidays) # Boxing Day def test_chingming_festival(self): # This is the same as the Taiwan test, just different spelling # Could move this into a Core test self.assertIn(date(2005, 4, 5), self.cal.holidays_set(2005)) self.assertIn(date(2006, 4, 5), self.cal.holidays_set(2006)) self.assertIn(date(2007, 4, 5), self.cal.holidays_set(2007)) self.assertIn(date(2008, 4, 4), self.cal.holidays_set(2008)) self.assertIn(date(2010, 4, 5), self.cal.holidays_set(2010)) self.assertIn(date(2011, 4, 5), self.cal.holidays_set(2011)) self.assertIn(date(2012, 4, 4), self.cal.holidays_set(2012)) self.assertIn(date(2013, 4, 4), self.cal.holidays_set(2013)) self.assertIn(date(2014, 4, 5), self.cal.holidays_set(2014)) self.assertIn(date(2015, 4, 4), self.cal.holidays_set(2015)) self.assertIn(date(2016, 4, 4), self.cal.holidays_set(2016)) self.assertIn(date(2017, 4, 4), self.cal.holidays_set(2017)) self.assertIn(date(2018, 4, 5), self.cal.holidays_set(2018)) def test_holidays_2020(self): # https://www.gov.hk/en/about/abouthk/holiday/2020.htm holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 25), holidays) # Chinese new year self.assertIn(date(2020, 1, 27), holidays) # Chinese new year self.assertIn(date(2020, 1, 28), holidays) # Chinese new year self.assertIn(date(2020, 4, 4), holidays) # Ching Ming self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 11), holidays) # Day after Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 4, 30), holidays) # Buddha's Birthday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 6, 25), holidays) # Tuen Ng Festival self.assertIn(date(2020, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2020, 10, 1), holidays) # National Day self.assertIn(date(2020, 10, 2), holidays) # Day after Mid-Autumn observed = self.cal.observed_holidays(2020) self.assertIn(date(2020, 10, 26), observed) # Chung Yeung Festival self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 26), holidays) # Boxing Day # Special: Boxing day is not shifted, because it's not a SUN self.assertNotIn(date(2020, 12, 28), holidays) def test_holidays_2021(self): # https://www.gov.hk/en/about/abouthk/holiday/2021.htm holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year self.assertIn(date(2021, 2, 12), holidays) # Chinese new year self.assertIn(date(2021, 2, 13), holidays) # Chinese new year self.assertIn(date(2021, 2, 14), holidays) # Chinese new year (SUN) observed = self.cal.observed_holidays(2021) self.assertIn(date(2021, 2, 15), observed) # Chinese new year self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 3), holidays) # Day after Good Friday self.assertIn(date(2021, 4, 4), holidays) # Ching Ming self.assertIn(date(2021, 4, 5), holidays) # Ching Ming shift+Easter self.assertIn(date(2021, 4, 6), holidays) # Day after Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 19), holidays) # Buddha's Birthday self.assertIn(date(2021, 6, 14), holidays) # Tuen Ng Festival self.assertIn(date(2021, 7, 1), holidays) # HK SAR Establishment Day self.assertIn(date(2021, 9, 22), holidays) # Day after Mid-Autumn self.assertIn(date(2021, 10, 1), holidays) # National Day self.assertIn(date(2021, 10, 14), observed) # Chung Yeung Festival self.assertIn(date(2021, 12, 25), holidays) # Christmas Day self.assertIn(date(2021, 12, 27), observed) # First weekday after Xmas def test_are_saturdays_working_days(self): # Let's start with february 6th. start = date(2020, 2, 6) # If SAT was a non-working day, it would have been the 13th. self.assertEqual( self.cal.add_working_days(start, 5), date(2020, 2, 12) ) def test_no_duplicate_days(self): holidays = self.cal.holidays(2021) labels = [day[1] for day in holidays] labels_dedup = list(set(labels)) assert sorted(labels) == sorted(labels_dedup) class HongKongBankTest(HongKongTest): cal_class = HongKongBank def test_are_saturdays_working_days(self): # Let's start with february 6th. start = date(2020, 2, 6) # If SAT and SUN are non-working days self.assertEqual( self.cal.add_working_days(start, 5), date(2020, 2, 13) ) class JapanTest(GenericCalendarTest): cal_class = Japan def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 2, 11), holidays) # Foundation Day self.assertIn(date(2013, 3, 20), holidays) # Vernal Equinox Day self.assertIn(date(2013, 4, 29), holidays) # Showa Day self.assertIn(date(2013, 5, 3), holidays) # Constitution Memorial Day self.assertIn(date(2013, 5, 4), holidays) # Greenery Day self.assertIn(date(2013, 5, 5), holidays) # Children's Day self.assertIn(date(2013, 9, 23), holidays) # Autumnal Equinox Day self.assertIn(date(2013, 11, 3), holidays) # Culture Day self.assertIn(date(2013, 11, 23), holidays) # Labour Thanksgiving Day self.assertIn(date(2013, 12, 23), holidays) # The Emperor's Birthday # Variable days self.assertIn(date(2013, 1, 14), holidays) # Coming of Age Day self.assertIn(date(2013, 7, 15), holidays) # Marine Day self.assertIn(date(2013, 9, 16), holidays) # Respect-for-the-Aged Day self.assertIn(date(2013, 10, 14), holidays) # Health and Sports Day def test_year_2016(self): # Before 2016, no Mountain Day holidays = self.cal.holidays_set(2014) self.assertNotIn(date(2014, 8, 11), holidays) # Mountain Day holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 8, 11), holidays) # Mountain Day # After 2016, yes holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 8, 11), holidays) # Mountain Day holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 8, 11), holidays) # Mountain Day def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 14), holidays) # Coming of Age Day self.assertIn(date(2019, 5, 1), holidays) # Coronation Day self.assertIn(date(2019, 5, 6), holidays) # Children's Day self.assertIn(date(2019, 8, 12), holidays) # Mountain Day Observed self.assertIn(date(2019, 11, 4), holidays) # Culture Day Observed # retrieve the sports day label holidays = self.cal.holidays(2019) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[date(2019, 10, 14)], "Health and Sports Day") def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 7, 23), holidays) # Marine Day self.assertIn(date(2020, 7, 24), holidays) # Sports Day self.assertIn(date(2020, 8, 10), holidays) # Mountain Day adjustment self.assertNotIn(date(2020, 8, 11), holidays) # Mountain Day self.assertNotIn(date(2020, 12, 31), holidays) # New Year's Bank Day # retrieve the sports day label holidays = self.cal.holidays(2020) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[date(2020, 7, 24)], "Sports Day") def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 7, 22), holidays) # Marine Day self.assertIn(date(2021, 7, 23), holidays) # Sports Day self.assertIn(date(2021, 8, 8), holidays) # Mountain Day self.assertIn(date(2021, 8, 9), holidays) # Mountain Day Observed self.assertNotIn(date(2021, 7, 19), holidays) # Marine Day self.assertNotIn(date(2021, 8, 11), holidays) # Mountain Day self.assertNotIn(date(2021, 10, 11), holidays) # Sports Day # retrieve the sports day label holidays = self.cal.holidays(2021) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[date(2021, 7, 23)], "Sports Day") class JapanBankTest(GenericCalendarTest): cal_class = JapanBank def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 2), holidays) # New Year's Bank Day self.assertIn(date(2019, 1, 3), holidays) # New Year's Bank Day self.assertIn(date(2019, 1, 14), holidays) # Coming of Age Day self.assertIn(date(2019, 5, 3), holidays) # Constitution Memorial Day self.assertIn(date(2019, 11, 4), holidays) # Culture Day Observed self.assertIn(date(2019, 12, 31), holidays) # New Year's Bank Day def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 2), holidays) # New Year's Bank Day self.assertIn(date(2020, 1, 3), holidays) # New Year's Bank Day self.assertIn(date(2020, 12, 31), holidays) # New Year's Bank Day self.assertIn(date(2020, 8, 10), holidays) # Mountain Day adjustment self.assertNotIn(date(2020, 8, 11), holidays) # Mountain Day self.assertIn(date(2020, 7, 23), holidays) # Marine Day self.assertIn(date(2020, 7, 24), holidays) # Sports Day class MalaysiaTest(GenericCalendarTest): cal_class = Malaysia def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year's Day self.assertIn(date(2013, 1, 28), holidays) # Thaipusam self.assertIn(date(2013, 2, 1), holidays) # Federal Territory Day self.assertIn(date(2013, 2, 11), holidays) # 2nd day of Lunar NY self.assertIn(date(2013, 2, 12), holidays) # 1st day (Sun lieu) self.assertIn(date(2013, 5, 1), holidays) # Workers' Day self.assertIn(date(2013, 5, 24), holidays) # Vesak Day self.assertIn(date(2013, 8, 8), holidays) # 1st day eid-al-fitr self.assertIn(date(2013, 8, 9), holidays) # 2nd day eid-al-fitr self.assertIn(date(2013, 8, 31), holidays) # National Day self.assertIn(date(2013, 9, 16), holidays) # Malaysia Day self.assertIn(date(2013, 10, 15), holidays) # Hari Raya Haji self.assertIn(date(2013, 11, 2), holidays) # Deepavali self.assertIn(date(2013, 11, 5), holidays) # Islamic New Year self.assertIn(date(2013, 12, 25), holidays) # Xmas def test_year_2012(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 1), holidays) # New Year's Day self.assertIn(date(2012, 1, 24), holidays) # Federal Territory Day self.assertIn(date(2012, 2, 1), holidays) # 2nd day of Lunar NY self.assertIn(date(2012, 5, 1), holidays) # 1st day (Sun lieu) self.assertIn(date(2012, 5, 5), holidays) # Workers' Day self.assertIn(date(2012, 8, 19), holidays) # 1st day eid-al-fitr self.assertIn(date(2012, 8, 20), holidays) # 2nd day eid-al-fitr self.assertIn(date(2012, 8, 31), holidays) # National Day self.assertIn(date(2012, 9, 16), holidays) # Malaysia Day self.assertIn(date(2012, 10, 26), holidays) # Hari Raya Haji self.assertIn(date(2012, 11, 13), holidays) # Islamic New Year self.assertIn(date(2012, 11, 15), holidays) # Deepavali self.assertIn(date(2012, 12, 25), holidays) # Xmas def test_nuzul_al_quran(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 6, 12), holidays) holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 6, 1), holidays) def test_fix_deepavali_2018(self): holidays = self.cal.holidays(2018) holidays = dict(holidays) deepavali = date(2018, 11, 6) self.assertIn(deepavali, holidays) self.assertEqual(holidays[deepavali], "Deepavali") def test_msia_thaipusam(self): # we only have them for years 2010-2024 self.assertEqual(set(self.cal.MSIA_THAIPUSAM), set(range(2010, 2025))) def test_missing_deepavali(self): save_2020 = self.cal.MSIA_DEEPAVALI[2020] del self.cal.MSIA_DEEPAVALI[2020] with self.assertRaises(KeyError): self.cal.holidays(2020) # Back to normal, to avoid breaking further tests self.cal.MSIA_DEEPAVALI[2020] = save_2020 def test_missing_thaipusam(self): save_2020 = self.cal.MSIA_THAIPUSAM[2020] del self.cal.MSIA_THAIPUSAM[2020] with self.assertRaises(KeyError): self.cal.holidays(2020) # Back to normal, to avoid breaking further tests self.cal.MSIA_THAIPUSAM[2020] = save_2020 def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Workers' Day") class QatarTest(GenericCalendarTest): cal_class = Qatar test_include_january_1st = False def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 7, 9), holidays) # start ramadan # warning, the official date was (2013, 8, 10) self.assertIn(date(2013, 8, 8), holidays) # eid al fitr # The official date was (2013, 10, 14) self.assertIn(date(2013, 10, 15), holidays) # eid al adha self.assertIn(date(2013, 10, 16), holidays) # eid al adha self.assertIn(date(2013, 10, 17), holidays) # eid al adha self.assertIn(date(2013, 10, 18), holidays) # eid al adha self.assertIn(date(2013, 12, 18), holidays) # National Day def test_weekend(self): # In Qatar, Week-end days are Friday / Sunday. weekend_day = date(2017, 5, 12) # This is a Friday non_weekend_day = date(2017, 5, 14) # This is a Sunday self.assertFalse(self.cal.is_working_day(weekend_day)) self.assertTrue(self.cal.is_working_day(non_weekend_day)) class SingaporeTest(GenericCalendarTest): cal_class = Singapore def test_CNY_2010(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 2, 14), holidays) # CNY1 self.assertIn(date(2010, 2, 15), holidays) # CNY2 self.assertIn(date(2010, 2, 16), holidays) # Rolled day for CNY def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year self.assertIn(date(2013, 2, 10), holidays) # CNY1 self.assertIn(date(2013, 2, 11), holidays) # CNY2 self.assertIn(date(2013, 2, 12), holidays) # Rolled day for CNY self.assertIn(date(2013, 3, 29), holidays) # Good Friday self.assertIn(date(2013, 5, 1), holidays) # Labour Day self.assertIn(date(2013, 5, 24), holidays) # Vesak Day self.assertIn(date(2013, 8, 8), holidays) # Hari Raya Puasa self.assertIn(date(2013, 8, 9), holidays) # National Day self.assertIn(date(2013, 10, 15), holidays) # Hari Raya Haji self.assertIn(date(2013, 11, 3), holidays) # Deepavali observed = self.cal.observed_holidays(2013) self.assertIn(date(2013, 11, 4), observed) # Deepavali shift self.assertIn(date(2013, 12, 25), holidays) # Christmas Day def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New Year self.assertIn(date(2018, 2, 16), holidays) # CNY self.assertIn(date(2018, 2, 17), holidays) # CNY self.assertIn(date(2018, 3, 30), holidays) # Good Friday self.assertIn(date(2018, 5, 1), holidays) # Labour Day self.assertIn(date(2018, 5, 29), holidays) # Vesak Day self.assertIn(date(2018, 6, 15), holidays) # Hari Raya Puasa self.assertIn(date(2018, 8, 9), holidays) # National Day self.assertIn(date(2018, 8, 22), holidays) # Hari Raya Haji self.assertIn(date(2018, 11, 6), holidays) # Deepavali self.assertIn(date(2018, 12, 25), holidays) # Christmas Day def test_fixed_holiday_shift(self): # Labour Day was on a Sunday in 2016 holidays = self.cal.holidays_set(2016) # Labour Day (sunday) self.assertIn(date(2016, 5, 1), holidays) # Shifted day (Monday) observed = self.cal.observed_holidays(2016) self.assertIn(date(2016, 5, 2), observed) def test_deepavali(self): # At the moment, we have values for deepavali only until year 2021 for year in range(2000, 2022): self.assertIn(year, self.cal.DEEPAVALI) def test_deepavali_current_year(self): # This is a regression test. We should be able to have the deepavali # value until this year and probably a few years in the future current_year = date.today().year self.assertIn(current_year, self.cal.DEEPAVALI) def test_deepavali_missing_year(self): with self.assertRaises(KeyError) as context: self.cal.holidays_set(1999) self.assertEqual( # Equivalent of the error msg context.exception.args[0], 'Missing date for Singapore Deepavali for year: 1999', ) class SouthKoreaTest(GenericCalendarTest): cal_class = SouthKorea def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 3, 1), holidays) # Independence day self.assertIn(date(2013, 5, 5), holidays) # children's day self.assertIn(date(2013, 6, 6), holidays) # Memorial day self.assertIn(date(2013, 8, 15), holidays) # Liberation day self.assertIn(date(2013, 10, 3), holidays) # National Foundation Day self.assertIn(date(2013, 10, 9), holidays) # Hangul Day self.assertIn(date(2013, 12, 25), holidays) # Christmas # Variable days self.assertIn(date(2013, 2, 9), holidays) self.assertIn(date(2013, 2, 10), holidays) self.assertIn(date(2013, 2, 11), holidays) self.assertIn(date(2013, 5, 17), holidays) self.assertIn(date(2013, 9, 18), holidays) self.assertIn(date(2013, 9, 19), holidays) self.assertIn(date(2013, 9, 20), holidays) class TaiwanTest(GenericCalendarTest): cal_class = Taiwan def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year self.assertIn(date(2013, 2, 9), holidays) # Chinese new year's eve self.assertIn(date(2013, 2, 10), holidays) # Chinese new year self.assertIn(date(2013, 2, 11), holidays) # Spring Festival self.assertIn(date(2013, 2, 12), holidays) # Spring Festival self.assertIn(date(2013, 2, 28), holidays) # 228 Peace Memorial Day self.assertIn(date(2013, 4, 4), holidays) # Children's Day self.assertIn(date(2013, 6, 12), holidays) # Dragon Boat Festival self.assertIn(date(2013, 9, 19), holidays) # Mid-Autumn Festival self.assertIn(date(2013, 10, 10), holidays) # National Day def test_qingming_festival(self): self.assertIn(date(2001, 4, 5), self.cal.holidays_set(2001)) self.assertIn(date(2002, 4, 5), self.cal.holidays_set(2002)) self.assertIn(date(2005, 4, 5), self.cal.holidays_set(2005)) self.assertIn(date(2006, 4, 5), self.cal.holidays_set(2006)) self.assertIn(date(2007, 4, 5), self.cal.holidays_set(2007)) self.assertIn(date(2008, 4, 4), self.cal.holidays_set(2008)) self.assertIn(date(2010, 4, 5), self.cal.holidays_set(2010)) self.assertIn(date(2011, 4, 5), self.cal.holidays_set(2011)) self.assertIn(date(2012, 4, 4), self.cal.holidays_set(2012)) self.assertIn(date(2013, 4, 4), self.cal.holidays_set(2013)) self.assertIn(date(2014, 4, 4), self.cal.holidays_set(2014)) def test_extra_day_2021_february(self): extra_day_feb_20 = date(2021, 2, 20) self.assertTrue(self.cal.is_working_day(extra_day_feb_20)) # Compute deltas with the extra-working day... five_days_after = self.cal.add_working_days( date(2021, 2, 19), 5 ) # Should've been on 26th, albeit the 20th self.assertEqual(five_days_after, date(2021, 2, 25)) def test_extra_day_2021_september(self): extra_day_sept_11 = date(2021, 9, 11) self.assertTrue(self.cal.is_working_day(extra_day_sept_11)) # Compute deltas with the extra-working day... five_days_after = self.cal.add_working_days( date(2021, 9, 10), 5 ) # Should've been on 17th, albeit the 11th self.assertEqual(five_days_after, date(2021, 9, 16)) class IsraelTest(GenericCalendarTest): cal_class = Israel test_include_january_1st = False def test_holidays_2017(self): calculated_holidays = self.cal.holidays_set(2017) known_holidays = { date(2017, 4, 10), # Passover (Pesach) date(2017, 4, 11), date(2017, 4, 16), date(2017, 4, 17), date(2017, 5, 1), # Independence Day (Yom Ha-Atzmaut) date(2017, 5, 2), date(2017, 9, 20), # Jewish New Year (Rosh Ha-Shana) date(2017, 9, 21), date(2017, 9, 22), date(2017, 9, 29), # Yom Kippur date(2017, 9, 30), date(2017, 10, 4), # Sukkot date(2017, 10, 5), date(2017, 10, 11), date(2017, 10, 12), date(2017, 5, 30), # Shavuot date(2017, 5, 31), } self.assertEqual(calculated_holidays, known_holidays) def test_holidays_2018(self): calculated_holidays = self.cal.holidays_set(2018) known_holidays = { date(2018, 3, 30), # Passover (Pesach) date(2018, 3, 31), date(2018, 4, 5), date(2018, 4, 6), date(2018, 4, 18), # Independence Day (Yom Ha-Atzmaut) date(2018, 4, 19), date(2018, 9, 9), # Rosh Hashana date(2018, 9, 10), date(2018, 9, 11), date(2018, 9, 18), # Yom Kippur date(2018, 9, 19), date(2018, 9, 23), # Sukkot date(2018, 9, 24), date(2018, 9, 30), date(2018, 10, 1), date(2018, 5, 19), # Shavuot date(2018, 5, 20), } self.assertEqual(calculated_holidays, known_holidays) def test_holidays_2019(self): calculated_holidays = self.cal.holidays_set(2019) known_holidays = { date(2019, 4, 19), # Passover (Pesach) date(2019, 4, 20), # Passover (Pesach) date(2019, 4, 25), # Passover (Pesach) date(2019, 4, 26), # Passover (Pesach) date(2019, 5, 8), # Independence Day (Yom Ha-Atzmaut) date(2019, 5, 9), # Independence Day (Yom Ha-Atzmaut) date(2019, 6, 8), # Shavuot date(2019, 6, 9), # Shavuot date(2019, 9, 29), # Rosh Hashana date(2019, 9, 30), # Rosh Hashana date(2019, 10, 1), # Rosh Hashana date(2019, 10, 8), # Yom Kippur date(2019, 10, 9), # Yom Kippur date(2019, 10, 13), # Sukkot date(2019, 10, 14), # Sukkot date(2019, 10, 20), # Sukkot date(2019, 10, 21), # Sukkot } self.assertEqual(calculated_holidays, known_holidays) def test_holidays_2020(self): calculated_holidays = self.cal.holidays_set(2020) known_holidays = { date(2020, 9, 18), # Rosh Hashana Eve date(2020, 9, 19), # Rosh Hashana A date(2020, 9, 20), # Rosh Hashana B date(2020, 9, 27), # Kippur Eve date(2020, 9, 28), # Kippur date(2020, 10, 2), # Sukot A Eve date(2020, 10, 3), # Sukot A date(2020, 10, 9), # Sukot B Eve date(2020, 10, 10), # Sukot B date(2020, 4, 8), # Pesach A Eve date(2020, 4, 9), # Pesach A date(2020, 4, 14), # Pesach B Eve date(2020, 4, 15), # Pesach B date(2020, 4, 28), # Independence Day Eve date(2020, 4, 29), # Independence Day date(2020, 5, 28), # Shavuot Eve date(2020, 5, 29), # Shavuot } self.assertEqual(calculated_holidays, known_holidays) def test_holidays_2021(self): calculated_holidays = self.cal.holidays_set(2021) known_holidays = { date(2021, 9, 6), # Rosh Hashana Eve date(2021, 9, 7), # Rosh Hashana A date(2021, 9, 8), # Rosh Hashana B date(2021, 9, 15), # Kippur Eve date(2021, 9, 16), # Kippur date(2021, 9, 20), # Sukot A Eve date(2021, 9, 21), # Sukot A date(2021, 9, 27), # Sukot B Eve date(2021, 9, 28), # Sukot B date(2021, 3, 27), # Pesach A Eve date(2021, 3, 28), # Pesach A date(2021, 4, 2), # Pesach B Eve date(2021, 4, 3), # Pesach B date(2021, 4, 14), # Independence Day Eve date(2021, 4, 15), # Independence Day date(2021, 5, 16), # Shavuot Eve date(2021, 5, 17), # Shavuot } self.assertEqual(calculated_holidays, known_holidays) def test_is_holiday_performance(self): random_date = date(2019, 10, 9) japan_cal = Japan() timer = time.time() for i in range(30): japan_cal.is_holiday(random_date) japan_time = time.time() - timer timer = time.time() for i in range(30): self.cal.is_holiday(random_date) israel_time = time.time() - timer self.assertGreater(japan_time * 3, israel_time) class Philippines(GenericCalendarTest): cal_class = Philippines def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year self.assertIn(date(2021, 2, 12), holidays) # Chinese New Year self.assertIn(date(2021, 2, 25), holidays) # EDSA Revolution self.assertIn(date(2021, 4, 1), holidays) # Maundy Thursday self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 3), holidays) # Black Saturday self.assertIn(date(2021, 4, 4), holidays) # Easter Sunday self.assertIn(date(2021, 4, 9), holidays) # Araw ng Kagitingan self.assertIn(date(2021, 5, 1), holidays) # Labor Day self.assertIn(date(2021, 5, 13), holidays) # Eid'l Fitr self.assertIn(date(2021, 6, 12), holidays) # Independence Day self.assertIn(date(2021, 7, 20), holidays) # Eid'l Adha self.assertIn(date(2021, 8, 21), holidays) # Ninoy Aquino Day self.assertIn(date(2021, 8, 30), holidays) # National Heroes' Day self.assertIn(date(2021, 11, 1), holidays) # All Saints' Day self.assertIn(date(2021, 11, 2), holidays) # All Souls Day self.assertIn(date(2021, 11, 30), holidays) # Bonifacio Day self.assertIn(date(2021, 12, 8), holidays) # Immaculate Conception self.assertIn(date(2021, 12, 24), holidays) # Christmas Eve self.assertIn(date(2021, 12, 25), holidays) # Christmas Day self.assertIn(date(2021, 12, 30), holidays) # Rizal Day self.assertIn(date(2021, 12, 31), holidays) # New Year's Eve def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 25), holidays) # Chinese New Year self.assertIn(date(2020, 2, 25), holidays) # EDSA Revolution self.assertIn(date(2020, 4, 9), holidays) # Araw ng Kagitingan self.assertIn(date(2020, 4, 9), holidays) # Maundy Thursday self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 11), holidays) # Black Saturday self.assertIn(date(2020, 4, 12), holidays) # Easter Sunday self.assertIn(date(2020, 5, 1), holidays) # Labor Day self.assertIn(date(2020, 5, 24), holidays) # Eid'l Fitr self.assertIn(date(2020, 6, 12), holidays) # Independence Day self.assertIn(date(2020, 7, 31), holidays) # Eid'l Adha self.assertIn(date(2020, 8, 21), holidays) # Ninoy Aquino Day self.assertIn(date(2020, 8, 30), holidays) # National Heroes' Day self.assertIn(date(2020, 11, 1), holidays) # All Saints' Day self.assertIn(date(2020, 11, 2), holidays) # All Souls Day self.assertIn(date(2020, 11, 30), holidays) # Bonifacio Day self.assertIn(date(2020, 12, 8), holidays) # Immaculate Conception self.assertIn(date(2020, 12, 24), holidays) # Christmas Eve self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 30), holidays) # Rizal Day self.assertIn(date(2020, 12, 31), holidays) # New Year's Eve class KazakhstanTest(GenericCalendarTest): cal_class = Kazakhstan def test_year_2006(self): holidays = self.cal.holidays_set(2006) self.assertIn(date(2006, 1, 1), holidays) # New Year self.assertIn(date(2006, 1, 2), holidays) # New Year Holiday self.assertIn(date(2006, 3, 8), holidays) # International Women's Day self.assertIn(date(2006, 3, 21), holidays) # Nauryz Meyramy self.assertIn(date(2006, 3, 22), holidays) # Nauryz Meyramy self.assertIn(date(2006, 3, 23), holidays) # Nauryz Meyramy self.assertIn(date(2006, 5, 1), holidays) # Unity Day self.assertIn(date(2006, 5, 9), holidays) # Day of victory self.assertIn(date(2006, 7, 6), holidays) # Capital City Day self.assertIn(date(2006, 8, 30), holidays) # Constitution Day self.assertIn(date(2006, 12, 16), holidays) # Independence Day self.assertIn(date(2006, 12, 17), holidays) # Independence Day def test_year_2012(self): holidays = self.cal.holidays_set(2012) assert len(holidays) == 14 self.assertIn(date(2012, 1, 1), holidays) # New Year self.assertIn(date(2012, 1, 2), holidays) # New Year Holiday self.assertIn(date(2012, 1, 7), holidays) # Orthodox Christmas self.assertIn(date(2012, 3, 8), holidays) # International Women's Day self.assertIn(date(2012, 3, 21), holidays) # Nauryz Meyramy self.assertIn(date(2012, 3, 22), holidays) # Nauryz Meyramy self.assertIn(date(2012, 3, 23), holidays) # Nauryz Meyramy self.assertIn(date(2012, 5, 1), holidays) # Unity Day self.assertIn(date(2012, 5, 9), holidays) # Day of victory self.assertIn(date(2012, 7, 6), holidays) # Capital City Day self.assertIn(date(2012, 8, 30), holidays) # Constitution Day self.assertIn(date(2012, 10, 26), holidays) # Kurban Ait (Eid al-Adha) self.assertIn(date(2012, 12, 16), holidays) # Independence Day self.assertIn(date(2012, 12, 17), holidays) # Independence Day def test_year_2016(self): holidays = self.cal.holidays_set(2016) assert len(holidays) == 16 self.assertIn(date(2016, 1, 1), holidays) # New Year self.assertIn(date(2016, 1, 2), holidays) # New Year Holiday self.assertIn(date(2016, 1, 7), holidays) # Orthodox Christmas self.assertIn(date(2016, 3, 8), holidays) # International Women's Day self.assertIn(date(2016, 3, 21), holidays) # Nauryz Meyramy self.assertIn(date(2016, 3, 22), holidays) # Nauryz Meyramy self.assertIn(date(2016, 3, 23), holidays) # Nauryz Meyramy self.assertIn(date(2016, 5, 1), holidays) # Unity Day self.assertIn(date(2016, 5, 7), holidays) # Defender of the Fatherland self.assertIn(date(2016, 5, 9), holidays) # Day of victory self.assertIn(date(2016, 7, 6), holidays) # Capital City Day self.assertIn(date(2016, 8, 30), holidays) # Constitution Day self.assertIn(date(2016, 9, 13), holidays) # Kurban Ait (Eid al-Adha) self.assertIn(date(2016, 12, 1), holidays) # First President Day self.assertIn(date(2016, 12, 16), holidays) # Independence Day self.assertIn(date(2016, 12, 17), holidays) # Independence Day def test_year_2020(self): holidays = self.cal.holidays_set(2020) assert len(holidays) == 16 self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 2), holidays) # New Year Holiday self.assertIn(date(2020, 1, 7), holidays) # Orthodox Christmas self.assertIn(date(2020, 3, 8), holidays) # International Women's Day self.assertIn(date(2020, 3, 21), holidays) # Nauryz Meyramy self.assertIn(date(2020, 3, 22), holidays) # Nauryz Meyramy self.assertIn(date(2020, 3, 23), holidays) # Nauryz Meyramy self.assertIn(date(2020, 5, 1), holidays) # Unity Day self.assertIn(date(2020, 5, 7), holidays) # Defender of the Fatherland self.assertIn(date(2020, 5, 9), holidays) # Day of victory self.assertIn(date(2020, 7, 6), holidays) # Capital City Day self.assertIn(date(2020, 7, 31), holidays) # Kurban Ait (Eid al-Adha) self.assertIn(date(2020, 8, 30), holidays) # Constitution Day self.assertIn(date(2020, 12, 1), holidays) # First President Day self.assertIn(date(2020, 12, 16), holidays) # Independence Day self.assertIn(date(2020, 12, 17), holidays) # Independence Day calendra-7.9.0/calendra/tests/test_astronomy.py000066400000000000000000000066501457013633400216740ustar00rootroot00000000000000import pytest from datetime import date from math import pi from unittest.mock import patch from skyfield.api import Loader from skyfield_data import get_skyfield_data_path from ..skyfield_astronomy import ( calculate_equinoxes, solar_term, newton_angle_function, ) def test_calculate_some_equinoxes(): assert calculate_equinoxes(2010) == (date(2010, 3, 20), date(2010, 9, 23)) assert calculate_equinoxes(2010, 'Asia/Taipei') == ( date(2010, 3, 21), date(2010, 9, 23) ) assert calculate_equinoxes(2013) == (date(2013, 3, 20), date(2013, 9, 22)) assert calculate_equinoxes(2014) == (date(2014, 3, 20), date(2014, 9, 23)) assert calculate_equinoxes(2020) == (date(2020, 3, 20), date(2020, 9, 22)) def test_qingming_festivals(): assert solar_term(2001, 15) == date(2001, 4, 4) assert solar_term(2001, 15, 'Asia/Taipei') == date(2001, 4, 5) assert solar_term(2011, 15) == date(2011, 4, 5) assert solar_term(2014, 15) == date(2014, 4, 4) assert solar_term(2016, 15) == date(2016, 4, 4) assert solar_term(2017, 15) == date(2017, 4, 4) def test_qingming_festivals_hk(): assert solar_term(2018, 15, 'Asia/Hong_Kong') == date(2018, 4, 5) assert solar_term(2019, 15, 'Asia/Hong_Kong') == date(2019, 4, 5) assert solar_term(2020, 15, 'Asia/Hong_Kong') == date(2020, 4, 4) assert solar_term(2021, 15, 'Asia/Hong_Kong') == date(2021, 4, 4) @pytest.fixture(scope='session') def params_newton_angle(): """ Session-scoped fixture to "cache" the newton angle func parameters """ load = Loader(get_skyfield_data_path()) ts = load.timescale() planets = load('de421.bsp') earth = planets['earth'] sun = planets['sun'] jan_first = ts.utc(date(2021, 1, 1)) t0 = ts.tt_jd(jan_first.tt).tt return t0, ts, earth, sun def test_newton_angle_function_normal_range(params_newton_angle): """ Test the newton angle func when the longitude is in the range [-pi, +pi]. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = pi assert newton_angle_function(t0, ts, 0, earth, sun) == -pi def test_newton_angle_function_above_pi(params_newton_angle): """ Test the newton angle function when the longitude is > +pi. This should not happen, but it was implemented in the function, so in order to make sure that the resulting angle is always in the range [-pi, +pi], we added these tests with those out of range values. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = pi + 0.1 expected = pytest.approx(-.1) assert newton_angle_function(t0, ts, 0, earth, sun) == expected def test_newton_angle_function_below_minus_pi(params_newton_angle): """ Test the newton angle function when the longitude is < -pi. This should not happen, but it was implemented in the function, so in order to make sure that the resulting angle is always in the range [-pi, +pi], we added these tests with those out of range values. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = -pi - 0.1 expected = pytest.approx(.1) assert newton_angle_function(t0, ts, 0, earth, sun) == expected calendra-7.9.0/calendra/tests/test_brazil.py000066400000000000000000001030451457013633400211200ustar00rootroot00000000000000from datetime import date from unittest import TestCase from . import GenericCalendarTest from ..america import ( Brazil, BrazilSaoPauloState, BrazilAcre, BrazilAlagoas, BrazilAmapa, BrazilAmazonas, BrazilBahia, BrazilCeara, BrazilDistritoFederal, BrazilEspiritoSanto, BrazilGoias, BrazilMaranhao, BrazilMinasGerais, BrazilMatoGrosso, BrazilMatoGrossoDoSul, BrazilPara, BrazilParaiba, BrazilPernambuco, BrazilPiaui, BrazilParana, BrazilRioDeJaneiro, BrazilRioGrandeDoNorte, BrazilRioGrandeDoSul, BrazilRondonia, BrazilRoraima, BrazilSantaCatarina, BrazilSergipe, BrazilTocantins, # Cities BrazilSaoPauloCity, BrazilVitoriaCity, BrazilVilaVelhaCity, BrazilCariacicaCity, BrazilGuarapariCity, BrazilSerraCity, BrazilRioBrancoCity, BrazilMaceioCity, BrazilManausCity, BrazilMacapaCity, BrazilSalvadorCity, BrazilFortalezaCity, BrazilGoianiaCity, BrazilBeloHorizonteCity, BrazilCampoGrandeCity, BrazilCuiabaCity, BrazilBelemCity, BrazilJoaoPessoaCity, BrazilRecifeCity, BrazilTeresinaCity, BrazilCuritibaCity, BrazilNatalCity, BrazilPortoVelhoCity, BrazilBoaVistaCity, BrazilPortoAlegreCity, BrazilChapecoCity, BrazilFlorianopolisCity, BrazilJoinvilleCity, BrazilAracajuCity, BrazilSorocabaCity, BrazilPalmasCity, # Banks BrazilBankCalendar, ) from ..america.brazil import IBGE_REGISTER, IBGE_TUPLE class BrazilTest(GenericCalendarTest): cal_class = Brazil test_include_consciencia_negra = False test_include_immaculate_conception = False def test_year_2013_federal(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 4, 21), holidays) # Tiradentes self.assertIn(date(2013, 5, 1), holidays) # Dia do trabalhador self.assertIn(date(2013, 9, 7), holidays) # Dia da Independência self.assertIn(date(2013, 10, 12), holidays) # Nossa Senhora Aparecida self.assertIn(date(2013, 11, 2), holidays) # Finados self.assertIn(date(2013, 11, 15), holidays) # Proclamação da República self.assertIn(date(2013, 12, 25), holidays) # Natal def test_consciencia_negra(self): # Consciência Negra day is not a national holiday # It's triggered in the appropriate classes, so this test needs to # be overwritten. month, day = self.cal.consciencia_negra_day consciencia_negra_day = date(self.year, month, day) holidays = self.cal.holidays_set(self.year) if self.test_include_consciencia_negra: # Included where needed self.assertIn(consciencia_negra_day, holidays) else: # By default, not in the holidays. self.assertNotIn(consciencia_negra_day, holidays) def test_immaculate_conception(self): # Immaculate Conception is not a national holiday # It's triggered in the appropriate classes, so this test needs to # be overwritten. immaculate_conception_day = date(self.year, 12, 8) holidays = dict(self.cal.holidays(self.year)) if self.test_include_immaculate_conception: # Included where needed self.assertIn(immaculate_conception_day, holidays) # Test its label self.assertEqual( holidays[immaculate_conception_day], "Dia de Nossa Senhora da Conceição") else: # By default, not in the holidays. self.assertNotIn(immaculate_conception_day, holidays) class BrazilAcreTest(BrazilTest): cal_class = BrazilAcre def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 23), holidays) # Dia do evangélico self.assertIn(date(2017, 6, 15), holidays) # niversário do Acre self.assertIn(date(2017, 9, 5), holidays) # Dia da Amazônia # Assinatura do Tratado de Petrópolis self.assertIn(date(2017, 11, 17), holidays) # Início da Revolução Acreana self.assertIn(date(2017, 8, 6), holidays) class BrazilAlagoasTest(BrazilTest): cal_class = BrazilAlagoas test_include_consciencia_negra = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 6, 24), holidays) # São João self.assertIn(date(2017, 6, 29), holidays) # São Pedro # Emancipação política de Alagoas self.assertIn(date(2017, 9, 16), holidays) self.assertIn(date(2017, 11, 20), holidays) # Consciência Negra class BrazilAmapaTest(BrazilTest): cal_class = BrazilAmapa test_include_consciencia_negra = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Dia de São José sao_jose = date(2017, 3, 19) self.assertIn(sao_jose, holidays) # Check its label self.assertEqual( self.cal.get_holiday_label(sao_jose), "Dia de São José") self.assertIn(date(2017, 7, 25), holidays) # São Tiago self.assertIn(date(2017, 10, 5), holidays) # Criação do estado self.assertIn(date(2017, 11, 20), holidays) # Consciência Negra self.assertIn(date(2017, 9, 13), holidays) # Aniversário da Amapá class BrazilAmazonasTest(BrazilTest): cal_class = BrazilAmazonas test_include_consciencia_negra = True test_include_immaculate_conception = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Elevação do Amazonas á categoria de província self.assertIn(date(2017, 9, 5), holidays) self.assertIn(date(2017, 11, 20), holidays) # Consciência Negra # Dia de Nossa Senhora da Conceição self.assertIn(date(2017, 12, 8), holidays) # Label test holidays = self.cal.holidays(2017) class BrazilBahiaTest(BrazilTest): cal_class = BrazilBahia def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 7, 2), holidays) # Independência da Bahia class BrazilCearaTest(BrazilTest): cal_class = BrazilCeara def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 3, 19), holidays) # São José self.assertIn(date(2017, 3, 23), holidays) # Data Manga do Ceará self.assertIn(date(2017, 3, 25), holidays) # Aniversário do Ceará class BrazilDistritoFederalTest(BrazilTest): cal_class = BrazilDistritoFederal def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 4, 21), holidays) # Fundação de Brasília self.assertIn(date(2017, 11, 30), holidays) # Dia do Evangélico class BrazilEspiritoSantoTest(BrazilTest): cal_class = BrazilEspiritoSanto def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 10, 28), holidays) # Dia do Servidor Público class BrazilGoiasTest(BrazilTest): cal_class = BrazilGoias def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 10, 28), holidays) # Dia do Servidor Público class BrazilMaranhaoTest(BrazilTest): cal_class = BrazilMaranhao test_include_immaculate_conception = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Adesão do Maranhão á independência do Brasil self.assertIn(date(2017, 7, 28), holidays) # Dia de Nossa Senhora da Conceição self.assertIn(date(2017, 12, 8), holidays) class BrazilMinasGeraisTest(BrazilTest): cal_class = BrazilMinasGerais def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Aniversário de Minas Geraisl self.assertIn(date(2017, 4, 21), holidays) class BrazilMatoGrossoTest(BrazilTest): cal_class = BrazilMatoGrosso test_include_consciencia_negra = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 11, 29), holidays) # Consciência Negra class BrazilMatoGrossoDoSulTest(BrazilTest): cal_class = BrazilMatoGrossoDoSul def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 10, 11), holidays) # Criação do estado class BrazilParaTest(BrazilTest): cal_class = BrazilPara test_include_immaculate_conception = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Adesão do Grão-Pará á independência do Brasil self.assertIn(date(2017, 8, 15), holidays) class BrazilParaibaTest(BrazilTest): cal_class = BrazilParaiba def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 8, 5), holidays) # Fundação do Estado # Homenagem à memória do ex-presidente João Pessoa self.assertIn(date(2017, 7, 26), holidays) class BrazilPernambucoTest(BrazilTest): cal_class = BrazilPernambuco def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 6, 24), holidays) # São João class BrazilPiauiTest(BrazilTest): cal_class = BrazilPiaui def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Dia da Batalha do Jenipapo self.assertIn(date(2017, 3, 13), holidays) self.assertIn(date(2017, 10, 19), holidays) # Dia do Piauí class BrazilParanaTest(BrazilTest): cal_class = BrazilParana def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Aniversário do Paraná self.assertIn(date(2017, 12, 19), holidays) class BrazilRioDeJaneiroTest(BrazilTest): cal_class = BrazilRioDeJaneiro test_include_consciencia_negra = True test_include_immaculate_conception = True def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 2, 28), holidays) # Carnaval self.assertIn(date(2017, 4, 23), holidays) # Dia de São Jorge self.assertIn(date(2017, 10, 16), holidays) # Dia do Comércio # Dia do Funcionário Público self.assertIn(date(2017, 10, 28), holidays) # Dia da Consciência Negra consciencia_negra = date(2017, 11, 20) self.assertIn(consciencia_negra, holidays) # check its label self.assertEqual( self.cal.get_holiday_label(consciencia_negra), "Dia da Consciência Negra", ) # Dia de Nossa Senhora da Conceição self.assertIn(date(2017, 12, 8), holidays) def test_carnaval_label(self): holidays = self.cal.holidays(2017) holidays_dict = dict(holidays) label_carnaval = holidays_dict[date(2017, 2, 28)] self.assertEqual(label_carnaval, "Carnaval") class BrazilRioGrandeDoNorteTest(BrazilTest): cal_class = BrazilRioGrandeDoNorte def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Dua de São Pedro sao_pedro = date(2017, 6, 29) self.assertIn(sao_pedro, holidays) # Check the label self.assertEqual( self.cal.get_holiday_label(sao_pedro), "Dua de São Pedro" ) # Mártires de Cunhaú e Uruaçuu self.assertIn(date(2017, 10, 3), holidays) class BrazilRioGrandeDoSulTest(BrazilTest): cal_class = BrazilRioGrandeDoSul def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 9, 20), holidays) # Revolução Farroupilha class BrazilRondoniaTest(BrazilTest): cal_class = BrazilRondonia def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 4), holidays) # Criação do estado self.assertIn(date(2017, 6, 18), holidays) # Dia do Evangélico class BrazilRoraimaTest(BrazilTest): cal_class = BrazilRoraima def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 10, 5), holidays) # Criação de Roraima class BrazilSantaCatarinaTest(BrazilTest): cal_class = BrazilSantaCatarina def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Criação da capitania, separando-se de SP self.assertIn(date(2017, 8, 11), holidays) # Dia de Santa Catarina de Alexandria self.assertIn(date(2017, 11, 25), holidays) class SaoPauloStateTest(BrazilTest): cal_class = BrazilSaoPauloState def test_year_2013_state(self): holidays = self.cal.holidays_set(2013) # Revolução Constitucionalista de 1932 self.assertIn(date(2013, 7, 9), holidays) # Revolução Constitucionalista de 1932 self.assertIn(date(2013, 7, 9), holidays) class SaoPauloCityTest(SaoPauloStateTest): cal_class = BrazilSaoPauloCity test_include_consciencia_negra = True def test_year_2013_city(self): holidays = self.cal.holidays_set(2013) # Aniversário da Cidade de São Paulo self.assertIn(date(2013, 1, 25), holidays) self.assertIn(date(2013, 2, 12), holidays) # Carnaval # Dia da Consciência Negra consciencia_negra = date(2013, 11, 20) self.assertIn(consciencia_negra, holidays) # check its label self.assertEqual( self.cal.get_holiday_label(consciencia_negra), "Dia da Consciência Negra", ) self.assertIn(date(2013, 3, 31), holidays) # Páscoa self.assertIn(date(2013, 5, 30), holidays) # Corpus Christi # Variable day: Good Friday good_friday = date(2013, 3, 29) self.assertIn(good_friday, holidays) # Sexta-feira da Paixão # Label test self.assertEqual( self.cal.get_holiday_label(good_friday), "Sexta-feira da Paixão", ) def test_carnaval_label(self): holidays = self.cal.holidays(2013) holidays_dict = dict(holidays) label_carnaval = holidays_dict[date(2013, 2, 12)] self.assertEqual(label_carnaval, "Carnaval") class BrazilSergipeTest(BrazilTest): cal_class = BrazilSergipe def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) # Autonomia política de Sergipe self.assertIn(date(2017, 7, 8), holidays) class BrazilTocantinsTest(BrazilTest): cal_class = BrazilTocantins def test_year_2017_state(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # Instalação de Tocantins # Nossa Senhora da Natividade self.assertIn(date(2017, 9, 8), holidays) self.assertIn(date(2017, 10, 5), holidays) # Criação de Tocantins # Autonomia do estado de Tocantins self.assertIn(date(2017, 3, 18), holidays) class BrazilVitoriaCityTest(BrazilEspiritoSantoTest): """ Vitória city is in the Espírito Santo state """ cal_class = BrazilVitoriaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days self.assertIn(date(2017, 4, 24), holidays) # Nossa Senhora da Penha self.assertIn(date(2017, 9, 8), holidays) # Nossa Senhora da Vitória # Variable days: Corpus Christie corpus_christie = date(2017, 6, 15) self.assertIn(corpus_christie, holidays) # Variable days: Good friday good_friday = date(2017, 4, 14) self.assertIn(good_friday, holidays) # Test label self.assertEqual( self.cal.get_holiday_label(good_friday), "Paixão do Cristo", ) class BrazilVilaVelhaCityTest(BrazilEspiritoSantoTest): """ Vila Velha city is in the Espírito Santo state """ cal_class = BrazilVilaVelhaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Colonização do Solo Espírito-santense self.assertIn(date(2017, 5, 23), holidays) class BrazilCariacicaCityTest(BrazilEspiritoSantoTest): """ Cariacica city is in the Espírito Santo state """ cal_class = BrazilCariacicaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days self.assertIn(date(2017, 4, 13), holidays) # Nossa Senhora da Penha # São João Batista / Aniversãrio de Cariacica sao_joao = date(2017, 6, 24) self.assertIn(sao_joao, holidays) # Check São João label self.assertEqual( self.cal.get_holiday_label(sao_joao), "São João Batista / Aniversãrio de Cariacica" ) # Variable days: Corpus Christie corpus_christie = date(2017, 6, 15) self.assertIn(corpus_christie, holidays) # Variable days: Good friday good_friday = date(2017, 4, 14) self.assertIn(good_friday, holidays) # Test label self.assertEqual( self.cal.get_holiday_label(good_friday), "Paixão do Cristo", ) class BrazilGuarapariCityTest(BrazilEspiritoSantoTest): """ Guarapari city is in the Espírito Santo state """ cal_class = BrazilGuarapariCity test_include_consciencia_negra = True test_include_immaculate_conception = True def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 6, 29), holidays), # São Pedro self.assertIn(date(2017, 9, 19), holidays), # Emancipação de Guarapari self.assertIn(date(2017, 11, 29), holidays), # Consciência Negra self.assertIn(date(2017, 12, 8), holidays), # Nossa Senhora Conceição class BrazilSerraCityTest(BrazilEspiritoSantoTest): """ Serra city is in the Espírito Santo state """ cal_class = BrazilSerraCity test_include_immaculate_conception = True def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days self.assertIn(date(2017, 6, 29), holidays) # São Pedro self.assertIn(date(2017, 12, 8), holidays) # Nossa Senhora Conceição self.assertIn(date(2017, 12, 26), holidays) # Dia do Serrano # Variable days: Carnaval (Monday & Tuesday) self.assertIn(date(2017, 2, 27), holidays) # Monday self.assertIn(date(2017, 2, 28), holidays) # Tuesday # Variable days: Ash Wednesday (Quarta-feira de cinzas) ash_wednesday = date(2017, 3, 1) self.assertIn(ash_wednesday, holidays) # Test label self.assertEqual( self.cal.get_holiday_label(ash_wednesday), "Quarta-feira de cinzas", ) # Variable days: Good Friday (Paixão de Cristo) good_friday = date(2017, 4, 14) self.assertIn(good_friday, holidays) # Test label self.assertEqual( self.cal.get_holiday_label(good_friday), "Paixão do Cristo", ) def test_carnaval_label(self): holidays = self.cal.holidays(2017) holidays_dict = dict(holidays) label_carnaval = holidays_dict[date(2017, 2, 28)] self.assertEqual(label_carnaval, "Carnaval") class BrazilRioBrancoCityTest(BrazilAcreTest): """ Rio Branco is in the Acre state """ cal_class = BrazilRioBrancoCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Rio Branco self.assertIn(date(2017, 12, 28), holidays) class BrazilMaceioCityTest(BrazilAlagoasTest): """ Maceió is in the Alagoas state """ cal_class = BrazilMaceioCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Maceió self.assertIn(date(2017, 12, 5), holidays) class BrazilManausCityTest(BrazilAmazonasTest): """ Manaus is in the Amazonas state """ cal_class = BrazilManausCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Manaus self.assertIn(date(2017, 10, 24), holidays) class BrazilMacapaCityTest(BrazilAmapaTest): """ Macapá is in the Amapá state """ cal_class = BrazilMacapaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Macapá self.assertIn(date(2017, 2, 4), holidays) class BrazilSalvadorCityTest(BrazilBahiaTest): """ Salvador is in the Bahia state """ cal_class = BrazilSalvadorCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Salvador self.assertIn(date(2017, 3, 29), holidays) class BrazilFortalezaCityTest(BrazilCearaTest): """ Fortaleza is in the Ceará state """ cal_class = BrazilFortalezaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Fortaleza self.assertIn(date(2017, 4, 13), holidays) class BrazilGoianiaCityTest(BrazilGoiasTest): """ Goiânia is in the Goiás state """ cal_class = BrazilGoianiaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Goiânia self.assertIn(date(2017, 10, 24), holidays) class BrazilBeloHorizonteCityTest(BrazilMinasGeraisTest): """ Belo Horizonte is in the Minas Gerais state """ cal_class = BrazilBeloHorizonteCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Belo Horizonte self.assertIn(date(2017, 12, 12), holidays) class BrazilCampoGrandeCityTest(BrazilMatoGrossoDoSulTest): """ Campo Grande is in the Mato Grosso do Sul state """ cal_class = BrazilCampoGrandeCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Campo Grande self.assertIn(date(2017, 8, 26), holidays) class BrazilCuiabaCityTest(BrazilMatoGrossoTest): """ Cuiabá is in the Mato Grosso state """ cal_class = BrazilCuiabaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Cuiabá self.assertIn(date(2017, 4, 8), holidays) self.assertIn(date(2017, 4, 14), holidays) # good_friday self.assertIn(date(2017, 4, 16), holidays) # easter_sunday self.assertIn(date(2017, 6, 15), holidays) # corpus_christi def test_good_friday_label(self): holidays = self.cal.holidays(2017) holidays_dict = dict(holidays) good_friday_label = holidays_dict[date(2017, 4, 14)] self.assertEqual(good_friday_label, "Sexta-feira da Paixão") class BrazilBelemCityTest(BrazilParaTest): """ Belém is in the Pará state """ cal_class = BrazilBelemCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Belém self.assertIn(date(2017, 1, 12), holidays) class BrazilJoaoPessoaCityTest(BrazilParaibaTest): """ João Pessoa is in the Paraíba state """ cal_class = BrazilJoaoPessoaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de João Pessoa self.assertIn(date(2017, 8, 5), holidays) class BrazilRecifeCityTest(BrazilPernambucoTest): """ Recife is in the Pernambuco state """ cal_class = BrazilRecifeCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Recife self.assertIn(date(2017, 3, 12), holidays) class BrazilTeresinaCityTest(BrazilPiauiTest): """ Teresina is in the Piauí state """ cal_class = BrazilTeresinaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Teresina self.assertIn(date(2017, 8, 16), holidays) class BrazilCuritibaCityTest(BrazilParanaTest): """ Curitiba is in the Paraná state """ cal_class = BrazilCuritibaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Curitiba self.assertIn(date(2017, 3, 29), holidays) class BrazilNatalCityTest(BrazilRioGrandeDoNorteTest): """ Natal is in the Rio Grande do Norte state """ cal_class = BrazilNatalCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Natal self.assertIn(date(2017, 12, 25), holidays) class BrazilPortoVelhoCityTest(BrazilRondoniaTest): """ Porto Velho is in the Rio Grande do Norte state """ cal_class = BrazilPortoVelhoCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Porto Velho self.assertIn(date(2017, 10, 2), holidays) class BrazilBoaVistaCityTest(BrazilRoraimaTest): """ Boa Vista is in the Roraima state """ cal_class = BrazilBoaVistaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Boa Vista self.assertIn(date(2017, 6, 9), holidays) class BrazilPortoAlegreCityTest(BrazilRioGrandeDoSulTest): """ Porto Alegre is in the Rio Grande do Sul state """ cal_class = BrazilPortoAlegreCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Porto Alegre self.assertIn(date(2017, 3, 26), holidays) class BrazilChapecoCityTest(BrazilSantaCatarinaTest): """ Chapecó is in the Santa Catarina state """ cal_class = BrazilChapecoCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Chapecó self.assertIn(date(2017, 8, 25), holidays) class BrazilFlorianopolisCityTest(BrazilSantaCatarinaTest): """ Florianópolis is in the Santa Catarina state """ cal_class = BrazilFlorianopolisCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Florianópolis self.assertIn(date(2017, 3, 23), holidays) class BrazilJoinvilleCityTest(BrazilSantaCatarinaTest): """ Joinville is in the Santa Catarina state """ cal_class = BrazilJoinvilleCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Joinville self.assertIn(date(2017, 3, 9), holidays) class BrazilAracajuCityTest(BrazilSergipeTest): """ Aracajú is in the Sergipe state """ cal_class = BrazilAracajuCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Aracajú self.assertIn(date(2017, 3, 17), holidays) class BrazilSorocabaCityTest(SaoPauloStateTest): """ Sorocaba is in the São Paulo state """ cal_class = BrazilSorocabaCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Sorocaba self.assertIn(date(2017, 8, 15), holidays) class BrazilPalmasCityTest(BrazilTocantinsTest): """ Palmas is in the Tocantins state """ cal_class = BrazilPalmasCity def test_year_2017_city(self): holidays = self.cal.holidays_set(2017) # Fixed days # Aniversário de Palmas self.assertIn(date(2017, 5, 20), holidays) class BrazilBankCalendarTest(BrazilTest): cal_class = BrazilBankCalendar def test_year_2017_holidays(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # New year self.assertIn(date(2017, 2, 27), holidays) # Monday carnaval self.assertIn(date(2017, 2, 28), holidays) # Tuesday carnaval self.assertIn(date(2017, 3, 1), holidays) # Ash wednesday self.assertIn(date(2017, 4, 14), holidays) # Good friday self.assertIn(date(2017, 4, 21), holidays) # Tiradentes self.assertIn(date(2017, 5, 1), holidays) # Labour day self.assertIn(date(2017, 6, 15), holidays) # Corpus Christi self.assertIn(date(2017, 9, 7), holidays) # Independence day self.assertIn(date(2017, 10, 12), holidays) # Our Lady Aparecida self.assertIn(date(2017, 11, 2), holidays) # All Souls' Day self.assertIn(date(2017, 11, 15), holidays) # Republic day self.assertIn(date(2017, 12, 25), holidays) # Christmas Day self.assertIn(date(2017, 12, 29), holidays) # Last working day of year self.assertEqual(14, len(holidays)) def test_year_2017_find_next_working_day_for_new_year(self): new_year = date(2017, 1, 1) working_day = self.cal.find_following_working_day(new_year) self.assertEqual(working_day, date(2017, 1, 2)) def test_year_2017_find_next_working_day_for_monday_carnaval(self): monday_carnaval = date(2017, 2, 27) working_day = self.cal.find_following_working_day(monday_carnaval) self.assertEqual(working_day, date(2017, 3, 2)) def test_year_2017_find_next_working_day_for_tuesday_carnaval(self): tuesday_carnaval = date(2017, 2, 28) working_day = self.cal.find_following_working_day(tuesday_carnaval) self.assertEqual(working_day, date(2017, 3, 2)) def test_year_2017_find_next_working_day_for_good_friday(self): good_friday = date(2017, 4, 14) working_day = self.cal.find_following_working_day(good_friday) self.assertEqual(working_day, date(2017, 4, 17)) def test_year_2017_find_next_working_day_for_tiradentes(self): tiradentes = date(2017, 4, 21) working_day = self.cal.find_following_working_day(tiradentes) self.assertEqual(working_day, date(2017, 4, 24)) def test_year_2017_find_next_working_day_for_labour_day(self): labour_day = date(2017, 5, 1) working_day = self.cal.find_following_working_day(labour_day) self.assertEqual(working_day, date(2017, 5, 2)) def test_year_2017_find_next_working_day_for_corpus_christi(self): corpus_christi = date(2017, 6, 15) working_day = self.cal.find_following_working_day(corpus_christi) self.assertEqual(working_day, date(2017, 6, 16)) def test_year_2017_find_next_working_day_for_independence_day(self): independence_day = date(2017, 9, 7) working_day = self.cal.find_following_working_day(independence_day) self.assertEqual(working_day, date(2017, 9, 8)) def test_year_2017_find_next_working_day_for_our_lady_aparecida(self): our_lady_aparecida = date(2017, 10, 12) working_day = self.cal.find_following_working_day(our_lady_aparecida) self.assertEqual(working_day, date(2017, 10, 13)) def test_year_2017_find_next_working_day_for_our_all_souls(self): all_souls = date(2017, 11, 2) working_day = self.cal.find_following_working_day(all_souls) self.assertEqual(working_day, date(2017, 11, 3)) def test_year_2017_find_next_working_day_for_our_republic_day(self): republic_day = date(2017, 11, 15) working_day = self.cal.find_following_working_day(republic_day) self.assertEqual(working_day, date(2017, 11, 16)) def test_year_2017_find_next_working_day_for_our_christmas_day(self): christmas_day = date(2017, 12, 25) working_day = self.cal.find_following_working_day(christmas_day) self.assertEqual(working_day, date(2017, 12, 26)) def test_year_2017_find_next_working_day_for_last_day(self): # last day of year for only internal bank transactions last_day = date(2017, 12, 29) working_day = self.cal.find_following_working_day(last_day) self.assertEqual(working_day, date(2018, 1, 2)) def test_year_2017_find_next_working_day_for_already_working_day(self): already_working_day = date(2017, 7, 25) working_day = self.cal.find_following_working_day(already_working_day) self.assertEqual(working_day, date(2017, 7, 25)) def test_carnaval_label(self): holidays = self.cal.holidays(2017) holidays_dict = dict(holidays) label_carnaval = holidays_dict[date(2017, 2, 28)] self.assertEqual(label_carnaval, "Tuesday carnaval") def test_shift_last_day_of_the_year(self): # New Year's eve is on SAT holidays = self.cal.holidays_set(2022) # Shifted to the FRI before self.assertIn(date(2022, 12, 30), holidays) self.assertNotIn(date(2022, 12, 29), holidays) # New Year's eve is on SUN holidays = self.cal.holidays_set(2017) # Shifted to the FRI before self.assertNotIn(date(2017, 12, 30), holidays) self.assertIn(date(2017, 12, 29), holidays) class TestIBGERegister(TestCase): def test_register_length(self): # Each time another calendar will be added, this length should increase # This also fails when a key appears twice (typo mistake?) self.assertEqual(len(IBGE_REGISTER), len(IBGE_TUPLE)) def test_no_duplicate(self): # Check if a class doesn't appear twice with different keys values = set(IBGE_REGISTER.values()) self.assertEqual(len(IBGE_REGISTER.values()), len(values)) def test_all_are_brazilian_classes(self): for key, value in IBGE_TUPLE: self.assertTrue(issubclass(value, Brazil)) calendra-7.9.0/calendra/tests/test_canada.py000066400000000000000000000413141457013633400210440ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..core import MON from ..america.canada import ( Canada, Ontario, Quebec, BritishColumbia, Alberta, Saskatchewan, Manitoba, NewBrunswick, NovaScotia, PrinceEdwardIsland, Newfoundland, Yukon, NorthwestTerritories, Nunavut ) class CanadaTest(GenericCalendarTest): cal_class = Canada def test_holidays_2011(self): holidays = self.cal.holidays_set(2011) observed = self.cal.observed_holidays(2011) self.assertIn(date(2011, 1, 3), observed) self.assertIn(date(2011, 7, 1), holidays) self.assertIn(date(2011, 9, 5), holidays) self.assertIn(date(2011, 12, 26), holidays) def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) # New years shift self.assertIn(date(2012, 7, 2), observed) # Canada day shift self.assertIn(date(2012, 9, 3), holidays) # Labour day self.assertIn(date(2012, 12, 25), holidays) def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertNotIn(date(2013, 3, 29), holidays) # Good Friday not in QC self.assertNotIn(date(2013, 4, 1), holidays) # Easter Monday QC only self.assertIn(date(2013, 7, 1), holidays) self.assertIn(date(2013, 9, 2), holidays) self.assertIn(date(2013, 12, 25), holidays) def test_holidays_2017(self): observed = self.cal.observed_holidays(2017) self.assertIn(date(2017, 1, 2), observed) class OntarioTest(GenericCalendarTest): cal_class = Ontario def test_holidays_2010(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 12, 27), holidays) # Christmas day shift self.assertIn(date(2010, 12, 28), holidays) # Boxing day shift def test_holidays_2011(self): holidays = self.cal.holidays_set(2011) observed = self.cal.observed_holidays(2011) self.assertIn(date(2011, 1, 3), observed) self.assertIn(date(2011, 2, 21), holidays) # Family Day Ontario self.assertIn(date(2011, 4, 22), holidays) # Good Friday self.assertNotIn(date(2011, 4, 25), holidays) # Easter Monday self.assertIn(date(2011, 5, 23), holidays) # Victoria Day self.assertIn(date(2011, 7, 1), holidays) # Canada Day self.assertIn(date(2011, 8, 1), holidays) # Civic holiday self.assertIn(date(2011, 9, 5), holidays) # Labour Day self.assertIn(date(2011, 10, 10), holidays) # Canadian Thanksgiving self.assertIn(date(2011, 12, 26), holidays) self.assertIn(date(2011, 12, 27), holidays) # Boxing day shift def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertIn(date(2012, 2, 20), holidays) # Family Day Ontario self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertIn(date(2012, 12, 26), holidays) # Boxing day class QuebecTest(GenericCalendarTest): cal_class = Quebec def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 4, 6), holidays) # Good Friday self.assertIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 6, 24), holidays) # St Jean Baptise self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 12, 25), holidays) # Christmas day class BritishColumbiaTest(GenericCalendarTest): cal_class = BritishColumbia def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) # Family Day BC was not set in 2012 self.assertNotIn(date(2012, 2, 13), holidays) self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 8, 6), holidays) # BC Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 12, 25), holidays) # Christmas day def test_family_day(self): # From 2013 to 2018, Family Day was on 2nd MON of February for year in range(2013, 2019): holidays = dict(self.cal.holidays(year)) day = self.cal.get_nth_weekday_in_month(year, 2, MON, 2) self.assertIn(day, holidays) self.assertEqual(holidays[day], "Family Day") # As of 2019, it happens on 3rd MON of February for year in (2019, 2020, 2021): holidays = dict(self.cal.holidays(year)) day = self.cal.get_nth_weekday_in_month(year, 2, MON, 3) self.assertIn(day, holidays) self.assertEqual(holidays[day], "Family Day") class AlbertaTest(GenericCalendarTest): cal_class = Alberta def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 12, 25), holidays) # Christmas day class SaskatchewanTest(GenericCalendarTest): cal_class = Saskatchewan def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 11, 12), holidays) # Remembrance Day (Shift) self.assertIn(date(2012, 12, 25), holidays) # Christmas day class ManitobaTest(GenericCalendarTest): cal_class = Manitoba def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertIn(date(2012, 2, 20), holidays) # Louis Riel Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertNotIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertNotIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day class NewBrunswickTest(GenericCalendarTest): cal_class = NewBrunswick def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertNotIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertNotIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertNotIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day class NovaScotiaTest(GenericCalendarTest): cal_class = NovaScotia def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertNotIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertNotIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day def test_holidays_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 16), holidays) # Viola Desmond day class PrinceEdwardIslandTest(GenericCalendarTest): cal_class = PrinceEdwardIsland def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertIn(date(2012, 2, 20), holidays) # Islander Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertNotIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertNotIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day class NewfoundlandTest(GenericCalendarTest): cal_class = Newfoundland def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 3, 29), holidays) # Good Friday self.assertNotIn(date(2013, 4, 1), holidays) # Easter Monday self.assertIn(date(2013, 7, 1), holidays) self.assertIn(date(2013, 9, 2), holidays) self.assertIn(date(2013, 12, 25), holidays) class YukonTest(GenericCalendarTest): cal_class = Yukon def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 8, 20), holidays) # Discovery Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertNotIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day class NorthwestTerritoriesTest(GenericCalendarTest): cal_class = NorthwestTerritories def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertIn(date(2012, 6, 21), holidays) # National Aboriginal Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day class NunavutTests(GenericCalendarTest): cal_class = Nunavut def test_holidays_2012(self): holidays = self.cal.holidays_set(2012) observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) self.assertNotIn(date(2012, 2, 20), holidays) # Family Day self.assertIn(date(2012, 4, 6), holidays) # Good Friday self.assertNotIn(date(2012, 4, 9), holidays) # Easter Monday self.assertIn(date(2012, 5, 21), holidays) # Victoria Day self.assertIn(date(2012, 7, 1), holidays) # Canada Day self.assertIn(date(2012, 9, 3), holidays) # Labour Day self.assertIn(date(2012, 7, 9), holidays) # Nunavut Day self.assertNotIn(date(2012, 8, 6), holidays) # Civic Holiday self.assertNotIn(date(2012, 6, 21), holidays) # Nat. Aboriginal Day self.assertIn(date(2012, 10, 8), holidays) # Canadian Thanksgiving self.assertIn(date(2012, 11, 11), holidays) # Remembrance Day self.assertIn(date(2012, 11, 12), holidays) # Remembrance Day Shift self.assertIn(date(2012, 12, 25), holidays) # Christmas day self.assertNotIn(date(2012, 12, 26), holidays) # Boxing day def test_nunavut_shift(self): # Nunavut day happens on SAT, no shift holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 7, 9), holidays) self.assertNotIn(date(2016, 7, 10), holidays) # Nunavut day happens on SUN, shift to the next day holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 7, 9), holidays) self.assertIn(date(2017, 7, 10), holidays) calendra-7.9.0/calendra/tests/test_core.py000066400000000000000000000753731457013633400206010ustar00rootroot00000000000000from datetime import date from datetime import datetime from unittest import TestCase from unittest.mock import patch import dateutil.relativedelta as rd import pandas from . import CoreCalendarTest, GenericCalendarTest from ..core import Holiday from ..core import ( MON, TUE, THU, FRI, WED, SAT, SUN, ISO_TUE, ISO_FRI, Calendar, LunarMixin, WesternCalendar, CalverterMixin, IslamicMixin, daterange, ) from ..exceptions import UnsupportedDateType, CalendarError class CalendarTest(CoreCalendarTest): def test_private_variables(self): self.assertTrue(hasattr(self.cal, '_holidays')) private_holidays = self.cal._holidays self.assertTrue(isinstance(private_holidays, dict)) self.cal.holidays(2011) self.cal.holidays(2012) private_holidays = self.cal._holidays self.assertTrue(isinstance(private_holidays, dict)) self.assertIn(2011, self.cal._holidays) self.assertIn(2012, self.cal._holidays) def test_year(self): holidays = self.cal.holidays() self.assertTrue(isinstance(holidays, (tuple, list))) self.assertEqual(self.cal._holidays[self.year], holidays) def test_another_year(self): holidays = self.cal.holidays(2011) self.assertTrue(isinstance(holidays, (tuple, list))) self.assertEqual(self.cal._holidays[2011], holidays) def test_is_working_day(self): self.assertRaises( NotImplementedError, self.cal.is_working_day, date(2012, 1, 1)) def test_nth_weekday(self): # first monday in january 2013 self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 1, MON), date(2013, 1, 7) ) # second monday in january 2013 self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 1, MON, 2), date(2013, 1, 14) ) # let's test the limits # Jan 1st is a TUE self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 1, TUE), date(2013, 1, 1) ) # There's no 6th MONday self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 1, MON, 6), None ) def test_nth_weekday_start(self): # first thursday after 18th april start = date(2013, 4, 18) self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 4, THU, start=start), date(2013, 4, 18) ) # first friday after 18th april start = date(2013, 4, 18) self.assertEqual( Calendar.get_nth_weekday_in_month(2013, 4, FRI, start=start), date(2013, 4, 19) ) def test_last_weekday(self): # last monday in january 2013 self.assertEqual( Calendar.get_last_weekday_in_month(2013, 1, MON), date(2013, 1, 28) ) # last thursday self.assertEqual( Calendar.get_last_weekday_in_month(2013, 1, THU), date(2013, 1, 31) ) def test_get_next_weekday_after(self): # the first monday after Apr 1 2015 self.assertEqual( Calendar.get_first_weekday_after(date(2015, 4, 1), MON), date(2015, 4, 6) ) # the first tuesday after Apr 14 2015 self.assertEqual( Calendar.get_first_weekday_after(date(2015, 4, 14), TUE), date(2015, 4, 14) ) def test_get_iso_week_date(self): # Find the MON of the week 1 in 2021 self.assertEqual( Calendar.get_iso_week_date(2021, 1), date(2021, 1, 4) ) # Find the FRI of the week 1 in 2021 self.assertEqual( Calendar.get_iso_week_date(2021, 1, ISO_FRI), date(2021, 1, 8) ) # Find the TUE of the week 44 in 2021 self.assertEqual( Calendar.get_iso_week_date(2021, 44, ISO_TUE), date(2021, 11, 2) ) # Remove this test when dropping support for Python 3.7 @patch('calendra.core.sys') def test_get_iso_week_date_patched(self, mock_sys): # The Python 3.6-3.7 backport should always work mock_sys.version_info = (3, 6, 0) self.assertEqual( Calendar.get_iso_week_date(2021, 44, ISO_TUE), date(2021, 11, 2) ) class LunarCalendarTest(TestCase): def test_lunar_new_year(self): self.assertEqual( LunarMixin.lunar(2014, 1, 1), date(2014, 1, 31) ) class MockCalendar(Calendar): def holidays(self, year=None): return ( Holiday(date(year, 12, 25), 'Christmas'), Holiday(date(year, 1, 1), 'New year'), ) def get_weekend_days(self): return [] # no week-end, yes, it's sad class MockCalendarTest(CoreCalendarTest): cal_class = MockCalendar def test_holidays_set(self): self.assertIn( date(self.year, 12, 25), self.cal.holidays_set(self.year)) self.assertIn( date(self.year, 1, 1), self.cal.holidays_set(self.year)) def test_sorted_dates(self): holidays = list(self.cal.holidays(self.year)) day, label = holidays.pop() for next_day, label in holidays: self.assertTrue(day <= next_day) day = next_day def test_add_workingdays_simple(self): # day is out of non-working-day self.assertEqual( self.cal.add_working_days(date(self.year, 12, 20), 0), date(self.year, 12, 20) ) self.assertEqual( self.cal.add_working_days(date(self.year, 12, 20), 1), date(self.year, 12, 21) ) def test_add_workingdays_on_holiday(self): # day is in holidays self.assertEqual( self.cal.add_working_days(date(self.year, 12, 25), 0), date(self.year, 12, 25) ) self.assertEqual( self.cal.add_working_days(date(self.year, 12, 24), 1), date(self.year, 12, 26) ) self.assertEqual( self.cal.add_working_days(date(self.year, 12, 24), 2), date(self.year, 12, 27) ) def test_add_workingdays_span(self): day = date(self.year, 12, 20) # since this calendar has no weekends, we'll just have a 2-day-shift self.assertEqual( self.cal.add_working_days(day, 20), date(self.year + 1, 1, 11) ) def test_add_working_days_exceptions(self): day = date(self.year, 12, 20) christmas = date(self.year, 12, 25) boxing = date(self.year, 12, 26) # exceptional workday self.assertEqual( self.cal.add_working_days(day, 20, extra_working_days=[christmas]), date(self.year + 1, 1, 10) ) # exceptional holiday + exceptional workday self.assertEqual( self.cal.add_working_days(day, 20, extra_working_days=[christmas], extra_holidays=[boxing]), date(self.year + 1, 1, 11) ) def test_add_exceptions(self): december_20th = date(self.year, 12, 20) christmas = date(self.year, 12, 25) # target_working_day *is* a working day target_working_day = self.cal.add_working_days(december_20th, 1) # Add extra working days extra_working_days = [christmas] # add extra holidays extra_holidays = [target_working_day] self.assertFalse(self.cal.is_working_day(christmas)) self.assertTrue( self.cal.is_working_day(christmas, extra_working_days=extra_working_days)) self.assertTrue(self.cal.is_working_day(target_working_day)) self.assertFalse( self.cal.is_working_day(target_working_day, extra_holidays=extra_holidays)) # test is_holiday self.assertTrue(self.cal.is_holiday(christmas)) def test_get_holiday_label(self): self.assertEqual( self.cal.get_holiday_label(date(2014, 1, 1)), 'New year') self.assertIsNone( self.cal.get_holiday_label(date(2014, 1, 2))) def test_add_working_days_backwards(self): day = date(self.year, 1, 3) # since this calendar has no weekends, we'll just have a 1-day-shift self.assertEqual( self.cal.add_working_days(day, -7), date(self.year - 1, 12, 26) ) self.assertEqual( self.cal.sub_working_days(day, 7), date(self.year - 1, 12, 26) ) # Negative argument to sub_working_days -> converted to positive. self.assertEqual( self.cal.sub_working_days(day, -7), date(self.year - 1, 12, 26) ) class SimpleObservanceCalendar(Calendar): """ A simple calendar with a couple of holidays with typical observance rules: If a holiday falls on a weekend, then its observance is shifted to a nearby weekday. """ include_new_years_day = False FIXED_HOLIDAYS = ( Holiday( date(2000, 12, 24), 'Christmas Eve', indication='December 24th', observance_shift=dict(weekday=rd.FR(-1)), ), Holiday(date(2000, 12, 25), 'Christmas', indication='December 25th'), ) def get_weekend_days(self): return SAT, SUN class ObservanceCalendarTest(CoreCalendarTest): """ A simple calendar with days shifted for observance. """ cal_class = SimpleObservanceCalendar def test_observance(self): """ Each Holiday returned by the calendar should be aware of its indicated date and observance date. """ holidays = list(self.cal.holidays(2011)) assert len(holidays) == 2 xmas_eve, xmas_day = holidays assert xmas_eve == date(2011, 12, 24) assert xmas_eve.get_observed_date(self.cal) == date(2011, 12, 23) assert xmas_day == date(2011, 12, 25) assert xmas_day.get_observed_date(self.cal) == date(2011, 12, 26) class IslamicMixinTest(CoreCalendarTest): cal_class = IslamicMixin def test_year_conversion(self): days = self.cal.converted(2013) self.assertEqual(len(days), 365) class CalverterClassNoConversionMethod(CalverterMixin): pass class NoConversionMethodTest(TestCase): def test_no_conversion_method(self): with self.assertRaises(NotImplementedError): CalverterClassNoConversionMethod() class IncludeLaylatAlQadr(IslamicMixin): include_laylat_al_qadr = True class DoesNotIncludeLaylatAlQadr(IslamicMixin): include_laylat_al_qadr = False class LaylatAlQadrTest(TestCase): def test_warning_laylat_al_qadr(self): cal = IncludeLaylatAlQadr() with patch('warnings.warn') as patched: cal.get_islamic_holidays() patched.assert_called_with( 'The Islamic holiday named Laylat al-Qadr is decided by the ' 'religious authorities. It is not possible to compute it. ' "You'll have to add it manually." ) def test_no_warning_laylat_al_qadr(self): cal = DoesNotIncludeLaylatAlQadr() with patch('warnings.warn') as patched: cal.get_islamic_holidays() patched.assert_not_called() class MockChristianCalendar(WesternCalendar): # WesternCalendar inherits from ChristianMixin pass class MockChristianCalendarTest(CoreCalendarTest): cal_class = MockChristianCalendar def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertNotIn(date(2014, 1, 6), holidays) # Epiphany self.assertNotIn(date(2014, 3, 3), holidays) # Clean Monday self.assertNotIn(date(2014, 3, 5), holidays) # Ash Wednesday self.assertNotIn(date(2014, 3, 25), holidays) # Annunciation self.assertNotIn(date(2014, 4, 17), holidays) # Holy Thursday self.assertNotIn(date(2014, 4, 18), holidays) # 'Good Friday self.assertNotIn(date(2014, 4, 19), holidays) # Easter sat self.assertNotIn(date(2014, 4, 20), holidays) # Easter Sun self.assertNotIn(date(2014, 4, 21), holidays) # Easter Mon self.assertNotIn(date(2014, 5, 29), holidays) # Ascension self.assertNotIn(date(2014, 6, 8), holidays) # Whit Sunday self.assertNotIn(date(2014, 6, 9), holidays) # Whit Monday self.assertNotIn(date(2014, 6, 19), holidays) # Corp. Christi self.assertNotIn(date(2014, 8, 15), holidays) # Assumption self.assertNotIn(date(2014, 11, 1), holidays) # All Saints self.assertNotIn(date(2014, 12, 8), holidays) # Imm. Conc. self.assertNotIn(date(2014, 12, 24), holidays) # Xmas Eve self.assertNotIn(date(2014, 12, 26), holidays) # Boxing Day # The only Christian day that is a holiday for every calendar self.assertIn(date(2014, 12, 25), holidays) # XMas # Only 2 days: Jan 1st and Christmas self.assertEqual(len(holidays), 2) class NoWeekendCalendar(Calendar): """ This calendar class has no WEEKEND_DAYS and no `get_weekend_days()` method. It has to fail when trying to fetch its weekend days / holidays """ class NoWeekendCalendarTest(CoreCalendarTest): cal_class = NoWeekendCalendar def test_weekend(self): day = date(2017, 5, 13) # This is a Saturday with self.assertRaises(NotImplementedError): self.cal.is_working_day(day) day = date(2017, 5, 17) # This is a Wednesday with self.assertRaises(NotImplementedError): self.cal.is_working_day(day) class GenericCalendarTestTest(GenericCalendarTest): cal_class = NoWeekendCalendar def test_weekend_days(self): with self.assertRaises(AssertionError): super().test_weekend_days() class WeekendOnWednesdayCalendar(Calendar): """ This calendar class weekend days is on Wednesday and we don't overwrite the `get_weekend_days()` method. It should be fine. """ WEEKEND_DAYS = (WED,) class WeekendOnWednesdayCalendarTest(CoreCalendarTest): cal_class = WeekendOnWednesdayCalendar def test_weekend(self): day = date(2017, 5, 13) # This is a Saturday self.assertTrue(self.cal.is_working_day(day)) day = date(2017, 5, 17) # This is a Wednesday self.assertFalse(self.cal.is_working_day(day)) class OverwriteGetWeekendDaysCalendar(Calendar): """ This calendar class has no WEEKEND_DAYS and we overwrite its `get_weekend_days` method. Should work. """ def get_weekend_days(self): return WED, class OverwriteGetWeekendDaysCalendarTest(CoreCalendarTest): cal_class = OverwriteGetWeekendDaysCalendar def test_weekend(self): day = date(2017, 5, 13) # This is a Saturday self.assertTrue(self.cal.is_working_day(day)) day = date(2017, 5, 17) # This is a Wednesday self.assertFalse(self.cal.is_working_day(day)) class NoHolidayCalendar(Calendar): include_new_years_day = False WEEKEND_DAYS = (SAT, SUN) class WorkingDaysDeltatest(TestCase): def test_zero(self): days = ( date(2018, 12, 21), # a Thursday date(2018, 12, 23), # a Sunday date(2018, 12, 25), # a holiday in Christian calendars ) for day in days: cal = NoHolidayCalendar() self.assertEqual(cal.get_working_days_delta(day, day), 0) cal = MockChristianCalendar() self.assertEqual(cal.get_working_days_delta(day, day), 0) def test_no_holidays_simple(self): cal = NoHolidayCalendar() day1 = date(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta(day1, day2) # there are 3 days, because of the week-ends self.assertEqual(delta, 3) # No difference if you swap the two dates delta = cal.get_working_days_delta(day2, day1) self.assertEqual(delta, 3) def test_no_holidays_over_2_years(self): cal = NoHolidayCalendar() day1 = date(2018, 12, 21) day2 = date(2019, 1, 4) delta = cal.get_working_days_delta(day1, day2) # there are 10 days, because of the week-ends self.assertEqual(delta, 10) # No difference if you swap the two dates delta = cal.get_working_days_delta(day2, day1) self.assertEqual(delta, 10) def test_christian_simple(self): cal = MockChristianCalendar() day1 = date(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta(day1, day2) # there are 2 days, because of the week-end + Christmas Day self.assertEqual(delta, 2) # No difference if you swap the two dates delta = cal.get_working_days_delta(day2, day1) self.assertEqual(delta, 2) def test_christian_over_2_years(self): cal = MockChristianCalendar() day1 = date(2018, 12, 21) day2 = date(2019, 1, 4) delta = cal.get_working_days_delta(day1, day2) # there are 8 days, because of the week-ends + Xmas day + New Year self.assertEqual(delta, 8) # No difference if you swap the two dates delta = cal.get_working_days_delta(day2, day1) self.assertEqual(delta, 8) def test_with_datetimes(self): cal = MockChristianCalendar() day1 = datetime(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta(day1, day2) # there are 2 days, because of the week-end + Christmas Day self.assertEqual(delta, 2) # No difference if you swap the two dates delta = cal.get_working_days_delta(day2, day1) self.assertEqual(delta, 2) def test_with_including_first_day(self): # linked to #393 cal = MockChristianCalendar() day1 = date(2018, 12, 24) # December 24th: not holiday so working day day2 = date(2018, 12, 25) # December 25th: Christmas # not including the first day, should return 0 delta = cal.get_working_days_delta(day1, day2) self.assertEqual(delta, 0) # including the first day, should return 1 delta = cal.get_working_days_delta(day1, day2, include_start=True) self.assertEqual(delta, 1) def test_use_extra_working_days(self): cal = MockChristianCalendar() day1 = date(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta( day1, day2, extra_working_days=[date(2018, 12, 25)] ) # there are 3 days, because of the week-end # and Christmas Day is a working day self.assertEqual(delta, 3) # No difference if you swap the two dates delta = cal.get_working_days_delta( day2, day1, extra_working_days=[date(2018, 12, 25)]) self.assertEqual(delta, 3) def test_use_extra_holidays(self): cal = MockChristianCalendar() day1 = date(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta( day1, day2, extra_holidays=[date(2018, 12, 24)] ) # Only 1 day, because of the week-end + XMas + XMas Eve self.assertEqual(delta, 1) # No difference if you swap the two dates delta = cal.get_working_days_delta( day2, day1, extra_holidays=[date(2018, 12, 24)]) self.assertEqual(delta, 1) def test_use_both_extra(self): cal = MockChristianCalendar() day1 = date(2018, 12, 21) day2 = date(2018, 12, 26) delta = cal.get_working_days_delta( day1, day2, extra_working_days=[date(2018, 12, 25)], extra_holidays=[date(2018, 12, 24)] ) # Only 1 day, because of the week-end + XMas Eve # And Christmas is a working day self.assertEqual(delta, 2) # No difference if you swap the two dates delta = cal.get_working_days_delta( day2, day1, extra_working_days=[date(2018, 12, 25)], extra_holidays=[date(2018, 12, 24)]) self.assertEqual(delta, 2) class NoDocstring(Calendar): pass class EmptyDocstring(Calendar): "" class OneLineDocstring(Calendar): "One line" class MultipleLineDocstring(Calendar): """Multiple line docstrings can span over multiple lines. """ class MultipleLineEmptyFirstDocstring(Calendar): """ Multiple line empty first docstrings can span over multiple lines. """ class CalendarClassNameTest(TestCase): def test_no_docstring(self): self.assertEqual(NoDocstring.name, "NoDocstring") def test_empty_docstring(self): self.assertEqual(EmptyDocstring.name, "EmptyDocstring") def test_oneline_docstring(self): self.assertEqual(OneLineDocstring.name, "One line") def test_multiple_line_docstring(self): self.assertEqual(MultipleLineDocstring.name, "Multiple line") def test_multiple_line_empty_first_docstring(self): self.assertEqual( MultipleLineEmptyFirstDocstring.name, "Multiple line empty first" ) class TestAcceptableDateTypes(CoreCalendarTest): """ Test cases about accepted date and datetime types. """ cal_class = MockCalendar unsupported = ('hello', 1) def test_unsupported_type_is_working_day(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.is_working_day(arg) # Extra holidays optional argument for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.is_working_day( date(2018, 1, 1), extra_holidays=[arg] ) # Extra working days optional argument for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.is_working_day( date(2018, 1, 1), extra_working_days=[arg] ) def test_unsupported_type_is_holiday(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.is_holiday(arg) # Extra holidays optional argument for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.is_holiday( date(2018, 1, 1), extra_holidays=[arg] ) def test_unsupported_type_holiday_label(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.get_holiday_label(arg) def test_unsupported_type_add_sub_working_days(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.add_working_days(arg, 1) for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.sub_working_days(arg, 1) # Extra holidays optional argument for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.add_working_days( date(2018, 1, 1), 1, extra_holidays=[arg] ) # Extra working days optional argument for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.add_working_days( date(2018, 1, 1), 1, extra_working_days=[arg] ) # NOTE: no need to test "sub", they're calling each other. def test_unsupported_type_find_following_working_day(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.find_following_working_day(arg) def test_unsupported_type_get_nth_weekday_in_month(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.get_nth_weekday_in_month(2018, 1, MON, start=arg) def test_unsupported_type_get_working_days_delta(self): for arg in self.unsupported: with self.assertRaises(UnsupportedDateType): self.cal.get_working_days_delta(date(2018, 1, 1), arg) with self.assertRaises(UnsupportedDateType): self.cal.get_working_days_delta(arg, date(2018, 1, 1)) def test_datetime(self): self.assertFalse( self.cal.is_working_day(datetime(2014, 1, 1))) self.assertTrue( self.cal.is_holiday(datetime(2014, 1, 1))) def test_add_working_days_datetime(self): # datetime inside, date outside self.assertEqual( self.cal.add_working_days( datetime(self.year, 12, 20, 12, 34, 56), 0), date(self.year, 12, 20) ) self.assertEqual( self.cal.add_working_days( datetime(self.year, 12, 20, 12, 34, 56), 1), date(self.year, 12, 21) ) # Use the `keep_datetime` option self.assertEqual( self.cal.add_working_days( datetime(self.year, 12, 20, 12, 34, 56), 0, keep_datetime=True), datetime(self.year, 12, 20, 12, 34, 56) ) self.assertEqual( self.cal.add_working_days( datetime(self.year, 12, 20, 12, 34, 56), 1, keep_datetime=True), datetime(self.year, 12, 21, 12, 34, 56) ) def test_sub_working_days_datetime(self): # datetime inside, date outside self.assertEqual( self.cal.sub_working_days( datetime(self.year, 12, 20, 12, 34, 56), 0), date(self.year, 12, 20) ) self.assertEqual( self.cal.sub_working_days( datetime(self.year, 12, 20, 12, 34, 56), 1), date(self.year, 12, 19) ) # Use the `keep_datetime` option self.assertEqual( self.cal.sub_working_days( datetime(self.year, 12, 20, 12, 34, 56), 0, keep_datetime=True), datetime(self.year, 12, 20, 12, 34, 56) ) self.assertEqual( self.cal.sub_working_days( datetime(self.year, 12, 20, 12, 34, 56), 1, keep_datetime=True), datetime(self.year, 12, 19, 12, 34, 56) ) def test_get_holiday_label_with_datetime(self): self.assertEqual( self.cal.get_holiday_label(datetime(2014, 1, 1)), 'New year') self.assertIsNone( self.cal.get_holiday_label(datetime(2014, 1, 2))) class PandasTimestampTest(CoreCalendarTest): cal_class = MockCalendar def test_panda_type_is_working_day(self): self.assertFalse( self.cal.is_working_day(pandas.to_datetime("2018-1-1")) ) # Extra holidays optional argument self.assertFalse( self.cal.is_working_day( date(2018, 1, 2), extra_holidays=[pandas.to_datetime("2018-1-2")] ) ) # Extra working days optional argument self.assertTrue( self.cal.is_working_day( date(2018, 1, 1), extra_working_days=[pandas.to_datetime("2018-1-1")] ) ) def test_panda_type_is_holiday(self): self.assertTrue(self.cal.is_holiday(pandas.to_datetime("2018-1-1"))) # Extra holidays optional argument self.assertTrue( self.cal.is_holiday( date(2018, 2, 1), extra_holidays=[pandas.to_datetime("2018-2-1")] ) ) def test_panda_type_holiday_label(self): label = self.cal.get_holiday_label(pandas.to_datetime("2018-1-1")) self.assertEqual(label, "New year") def test_panda_type_add_sub_working_days(self): day = pandas.to_datetime("2018-12-24") next_day = self.cal.add_working_days(day, 1) self.assertEqual(next_day, date(2018, 12, 26)) previous_day = self.cal.sub_working_days(next_day, 1) self.assertEqual(previous_day, date(2018, 12, 24)) next_day = self.cal.add_working_days( date(2018, 12, 24), 1, extra_holidays=[pandas.to_datetime("2018-12-26")] ) self.assertEqual(next_day, date(2018, 12, 27)) next_day = self.cal.add_working_days( date(2018, 12, 24), 1, extra_working_days=[pandas.to_datetime("2018-12-25")] ) self.assertEqual(next_day, date(2018, 12, 25)) def test_unsupported_type_find_following_working_day(self): following_day = self.cal.find_following_working_day( pandas.to_datetime("2018-1-1") ) # No weekend days, the next day is "today" self.assertEqual(following_day, date(2018, 1, 1)) def test_unsupported_type_get_nth_weekday_in_month(self): start = pandas.to_datetime("2018-1-4") monday = self.cal.get_nth_weekday_in_month(2018, 1, MON, start=start) self.assertEqual(monday, date(2018, 1, 8)) def test_unsupported_type_get_working_days_delta(self): start, end = date(2018, 12, 23), pandas.to_datetime("2018-12-26") delta = self.cal.get_working_days_delta(start, end) self.assertEqual(delta, 2) delta = self.cal.get_working_days_delta(end, start) self.assertEqual(delta, 2) start, end = pandas.to_datetime("2018-12-23"), date(2018, 12, 26) delta = self.cal.get_working_days_delta(start, end) self.assertEqual(delta, 2) delta = self.cal.get_working_days_delta(end, start) self.assertEqual(delta, 2) class MockCalendarNoFatTuesdayLabel(WesternCalendar): fat_tuesday_label = None class FatTuesdayLabelTest(TestCase): def test_fat_tuesday_label(self): cal = MockCalendarNoFatTuesdayLabel() with self.assertRaises(CalendarError): cal.get_fat_tuesday(2020) def test_daterange_start_end(): start = date(2020, 4, 1) end = date(2020, 4, 10) date_list = list(daterange(start, end)) assert date_list == [ date(2020, 4, 1), date(2020, 4, 2), date(2020, 4, 3), date(2020, 4, 4), date(2020, 4, 5), date(2020, 4, 6), date(2020, 4, 7), date(2020, 4, 8), date(2020, 4, 9), date(2020, 4, 10), ] def test_daterange_end_start(): end = date(2020, 4, 1) start = date(2020, 4, 10) date_list = list(daterange(start, end)) assert date_list == [ date(2020, 4, 1), date(2020, 4, 2), date(2020, 4, 3), date(2020, 4, 4), date(2020, 4, 5), date(2020, 4, 6), date(2020, 4, 7), date(2020, 4, 8), date(2020, 4, 9), date(2020, 4, 10), ] def test_daterange_same_date(): # Stupid usecase, but nonetheless start = end = date(2020, 4, 1) date_list = list(daterange(start, end)) assert date_list == [date(2020, 4, 1)] calendra-7.9.0/calendra/tests/test_europe.py000066400000000000000000003235341457013633400211430ustar00rootroot00000000000000from datetime import date, timedelta, datetime from collections import Counter from unittest import TestCase from . import GenericCalendarTest from ..core import daterange, ISO_SAT from ..core import Holiday from ..europe import ( Austria, Bulgaria, Belarus, Belgium, CaymanIslands, Croatia, Cyprus, CzechRepublic, Denmark, Slovakia, Finland, Estonia, Sweden, France, FranceAlsaceMoselle, Georgia, Greece, Guernsey, Hungary, Iceland, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Monaco, Netherlands, NetherlandsWithSchoolHolidays, Norway, Poland, Portugal, Romania, Russia, Serbia, Slovenia, Ukraine, UnitedKingdom, UnitedKingdomNorthernIreland, EuropeanCentralBank, ) # Tests dedicated to Netherlands School holidays from ..europe.netherlands import ( SPRING_HOLIDAYS_EARLY_REGIONS, SUMMER_HOLIDAYS_EARLY_REGIONS, SUMMER_HOLIDAYS_LATE_REGIONS, ) class AustriaTest(GenericCalendarTest): cal_class = Austria def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Years day self.assertIn(date(2016, 1, 6), holidays) # Epiphany self.assertIn(date(2016, 3, 28), holidays) # easter monday self.assertIn(date(2016, 5, 1), holidays) # National Holiday self.assertIn(date(2016, 5, 5), holidays) # Ascension Day self.assertIn(date(2016, 5, 16), holidays) # Whit monday self.assertIn(date(2016, 5, 26), holidays) # Corpus Christi self.assertIn(date(2016, 8, 15), holidays) # Assumption self.assertIn(date(2016, 10, 26), holidays) # national day again self.assertIn(date(2016, 11, 1), holidays) # all saints self.assertIn(date(2016, 12, 8), holidays) # Immaculate conception self.assertIn(date(2016, 12, 25), holidays) # Xmas self.assertIn(date(2016, 12, 26), holidays) # St Stephens def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual(holidays[date(2020, 5, 1)], "State Holiday") # a.k.a. Staatsfeiertag class BelarusTest(GenericCalendarTest): cal_class = Belarus def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Years day self.assertIn(date(2019, 1, 2), holidays) # Day after NYE self.assertIn(date(2019, 1, 7), holidays) # Christmas (Orthodox) self.assertIn(date(2019, 3, 8), holidays) # International Women's Day self.assertIn(date(2019, 5, 1), holidays) # Labour Day self.assertIn(date(2019, 5, 7), holidays) # Radonitsa self.assertIn(date(2019, 5, 9), holidays) # Victory Day self.assertIn(date(2019, 7, 3), holidays) # Republic Day self.assertIn(date(2019, 11, 7), holidays) # October Revolution Day self.assertIn(date(2019, 12, 25), holidays) # Christmas (Catholic) def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Years day self.assertIn(date(2020, 1, 2), holidays) # Day after NYE self.assertIn(date(2020, 1, 7), holidays) # Christmas (Orthodox) self.assertIn(date(2020, 3, 8), holidays) # International Women's Day self.assertIn(date(2020, 4, 28), holidays) # Radonitsa self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 9), holidays) # Victory Day self.assertIn(date(2020, 7, 3), holidays) # Republic Day self.assertIn(date(2020, 11, 7), holidays) # October Revolution Day self.assertIn(date(2020, 12, 25), holidays) # Christmas (Catholic) class BulgariaTest(GenericCalendarTest): cal_class = Bulgaria def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "International Workers' Day") def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Year's Day self.assertIn(date(2019, 3, 3), holidays) # Liberation Day self.assertIn(date(2019, 3, 4), holidays) # Liberation Day (shift) self.assertIn(date(2019, 4, 26), holidays) # Good Friday self.assertIn(date(2019, 4, 27), holidays) # Holy Saturday self.assertIn(date(2019, 4, 28), holidays) # Easter day (sunday) self.assertIn(date(2019, 4, 29), holidays) # Easter Monday self.assertIn(date(2019, 5, 1), holidays) # International Workers' day self.assertIn(date(2019, 5, 6), holidays) # St George's Day self.assertIn(date(2019, 5, 24), holidays) # St Cyril & Methodius self.assertIn(date(2019, 9, 6), holidays) # Unification Day self.assertIn(date(2019, 9, 22), holidays) # Independence Day self.assertIn(date(2019, 9, 23), holidays) # Independence Day (shift) self.assertIn(date(2019, 12, 24), holidays) # Christmas Eve self.assertIn(date(2019, 12, 25), holidays) # Christmas 1 (FRI) self.assertIn(date(2019, 12, 26), holidays) # Christmas 2 (SAT) def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) observed = self.cal.observed_holidays(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year's Day self.assertIn(date(2020, 3, 3), holidays) # Liberation Day self.assertIn(date(2020, 4, 17), holidays) # Good Friday self.assertIn(date(2020, 4, 18), holidays) # Holy Saturday self.assertIn(date(2020, 4, 19), holidays) # Easter day (sunday) self.assertIn(date(2020, 4, 20), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # International Workers' day self.assertIn(date(2020, 5, 6), holidays) # St George's Day self.assertIn(date(2020, 5, 24), holidays) # St Cyril & Methodius self.assertIn(date(2020, 5, 25), holidays) # (shift) self.assertIn(date(2020, 9, 6), holidays) # Unification Day self.assertIn(date(2020, 9, 7), holidays) # Unification Day (shift) self.assertIn(date(2020, 9, 22), holidays) # Independence Day self.assertIn(date(2020, 12, 24), holidays) # Christmas Eve self.assertIn(date(2020, 12, 25), holidays) # Christmas 1 (FRI) self.assertIn(date(2020, 12, 26), holidays) # Christmas 2 (SAT) self.assertIn(date(2020, 12, 28), observed) # Christmas 2b (shift) def test_holidays_2021(self): holidays = self.cal.holidays_set(2021) observed = self.cal.observed_holidays(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year's Day self.assertIn(date(2021, 3, 3), holidays) # Liberation Day self.assertIn(date(2021, 4, 30), holidays) # Good Friday self.assertIn(date(2021, 5, 1), holidays) # Holy Saturday self.assertIn(date(2021, 5, 2), holidays) # Easter day (sunday) self.assertIn(date(2021, 5, 3), holidays) # Easter Monday # International Workers' day (in lieu, because easter) self.assertIn(date(2021, 5, 4), holidays) self.assertIn(date(2021, 5, 6), holidays) # St George's Day self.assertIn(date(2021, 5, 24), holidays) # St Cyril & Methodius self.assertIn(date(2021, 9, 6), holidays) # Unification Day self.assertIn(date(2021, 9, 22), holidays) # Independence Day self.assertIn(date(2021, 12, 24), holidays) # Christmas Eve self.assertIn(date(2021, 12, 25), holidays) # Christmas 1 (SAT) self.assertIn(date(2021, 12, 26), holidays) # Christmas 2 self.assertIn(date(2021, 12, 27), observed) # Christmas 2b self.assertIn(date(2021, 12, 28), observed) # Christmas 2c def test_holidays_2022(self): holidays = self.cal.holidays_set(2022) observed = self.cal.observed_holidays(2022) self.assertIn(date(2022, 1, 1), holidays) # New Year's Day self.assertIn(date(2022, 1, 3), holidays) # New Year's Day (shift) self.assertIn(date(2022, 3, 3), holidays) # Liberation Day self.assertIn(date(2022, 4, 22), holidays) # Good Friday self.assertIn(date(2022, 4, 23), holidays) # Holy Saturday self.assertIn(date(2022, 4, 24), holidays) # Easter day (sunday) self.assertIn(date(2022, 4, 25), holidays) # Easter Monday self.assertIn(date(2022, 5, 1), holidays) # International Workers' day self.assertIn(date(2022, 5, 2), holidays) # Labour day Shift self.assertIn(date(2022, 5, 6), holidays) # St George's Day self.assertIn(date(2022, 5, 24), holidays) # St Cyril & Methodius self.assertIn(date(2022, 9, 6), holidays) # Unification Day self.assertIn(date(2022, 9, 22), holidays) # Independence Day self.assertIn(date(2022, 12, 24), holidays) # Christmas Eve self.assertIn(date(2022, 12, 25), holidays) # Christmas 1 (SAT) self.assertIn(date(2022, 12, 26), holidays) # Christmas 2 self.assertIn(date(2022, 12, 27), observed) # Christmas 2b self.assertIn(date(2022, 12, 28), observed) # Christmas 2c class CaymanIslandsTest(GenericCalendarTest): cal_class = CaymanIslands def test_holidays_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 1, 28), holidays) # National Heroes Day self.assertIn(date(2013, 2, 13), holidays) # Ash Wednesday self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 20), holidays) # Discovery Day self.assertIn(date(2013, 6, 17), holidays) # Queen's Birthday self.assertIn(date(2013, 7, 1), holidays) # Constitution Day self.assertIn(date(2013, 11, 11), holidays) # Remembrance Day self.assertIn(date(2013, 12, 25), holidays) # XMas self.assertIn(date(2013, 12, 26), holidays) # Boxing Day def test_holidays_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) self.assertIn(date(2014, 1, 27), holidays) # National Heroes Day self.assertIn(date(2014, 3, 5), holidays) # Ash Wednesday self.assertIn(date(2014, 4, 18), holidays) # good friday self.assertIn(date(2014, 4, 21), holidays) # easter monday self.assertIn(date(2014, 5, 19), holidays) # Discovery Day self.assertIn(date(2014, 6, 16), holidays) # Queen's Birthday self.assertIn(date(2014, 7, 7), holidays) # Constitution Day self.assertIn(date(2014, 11, 10), holidays) # Remembrance Day self.assertIn(date(2014, 12, 25), holidays) # XMas self.assertIn(date(2014, 12, 26), holidays) # Boxing Day (on week-end) def test_holidays_2015(self): holidays = self.cal.holidays_set(2015) observed = self.cal.observed_holidays(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 1, 26), holidays) # National Heroes Day self.assertIn(date(2015, 2, 18), holidays) # Ash Wednesday self.assertIn(date(2015, 4, 3), holidays) # good friday self.assertIn(date(2015, 4, 6), holidays) # easter monday self.assertIn(date(2015, 5, 18), holidays) # Discovery Day self.assertIn(date(2015, 6, 15), holidays) # Queen's Birthday self.assertIn(date(2015, 7, 6), holidays) # Constitution Day self.assertIn(date(2015, 11, 9), holidays) # Remembrance Day self.assertIn(date(2015, 12, 25), holidays) # XMas self.assertIn(date(2015, 12, 26), holidays) # Boxing Day (on week-end) self.assertIn(date(2015, 12, 28), observed) # Boxing Day observed def test_holidays_2016(self): holidays = self.cal.holidays_set(2016) observed = self.cal.observed_holidays(2016) self.assertIn(date(2016, 1, 1), holidays) self.assertIn(date(2016, 1, 25), holidays) # National Heroes Day self.assertIn(date(2016, 2, 10), holidays) # Ash Wednesday self.assertIn(date(2016, 3, 25), holidays) # good friday self.assertIn(date(2016, 3, 28), holidays) # easter monday self.assertIn(date(2016, 5, 16), holidays) # Discovery Day self.assertIn(date(2016, 6, 13), holidays) # Queen's Birthday self.assertIn(date(2016, 7, 4), holidays) # Constitution Day self.assertIn(date(2016, 11, 14), holidays) # Remembrance Day self.assertIn(date(2016, 12, 26), observed) # XMas (in lieu) self.assertIn(date(2016, 12, 27), observed) # Boxing Day (in lieu) def test_holidays_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) self.assertNotIn(date(2017, 1, 2), holidays) # New Year boxing self.assertIn(date(2017, 1, 23), holidays) # National Heroes Day self.assertIn(date(2017, 3, 1), holidays) # Ash Wednesday self.assertIn(date(2017, 4, 14), holidays) # good friday self.assertIn(date(2017, 4, 17), holidays) # easter monday self.assertIn(date(2017, 5, 15), holidays) # Discovery Day self.assertIn(date(2017, 5, 24), holidays) # Election Day self.assertIn(date(2017, 6, 19), holidays) # Queen's Birthday self.assertIn(date(2017, 7, 3), holidays) # Constitution Day self.assertIn(date(2017, 11, 13), holidays) # Remembrance Day self.assertIn(date(2017, 12, 25), holidays) # XMas self.assertIn(date(2017, 12, 26), holidays) # Boxing Day def test_holidays_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) self.assertIn(date(2018, 1, 22), holidays) # National Heroes Day self.assertIn(date(2018, 2, 14), holidays) # Ash Wednesday self.assertIn(date(2018, 3, 30), holidays) # good friday self.assertIn(date(2018, 4, 2), holidays) # easter monday self.assertIn(date(2018, 5, 21), holidays) # Discovery Day self.assertIn(date(2018, 6, 11), holidays) # Queen's Birthday self.assertIn(date(2018, 7, 2), holidays) # Constitution Day self.assertIn(date(2018, 11, 12), holidays) # Remembrance Day self.assertIn(date(2018, 12, 25), holidays) # XMas self.assertIn(date(2018, 12, 26), holidays) # Boxing Day def test_holidays_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) self.assertIn(date(2019, 1, 28), holidays) # National Heroes Day self.assertIn(date(2019, 3, 6), holidays) # Ash Wednesday self.assertIn(date(2019, 4, 19), holidays) # good friday self.assertIn(date(2019, 4, 22), holidays) # easter monday self.assertIn(date(2019, 5, 20), holidays) # Discovery Day self.assertIn(date(2019, 6, 10), holidays) # Queen's Birthday self.assertIn(date(2019, 7, 1), holidays) # Constitution Day self.assertIn(date(2019, 11, 11), holidays) # Remembrance Day self.assertIn(date(2019, 12, 25), holidays) # XMas self.assertIn(date(2019, 12, 26), holidays) # Boxing Day def test_holidays_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) self.assertIn(date(2020, 1, 27), holidays) # National Heroes Day self.assertIn(date(2020, 2, 26), holidays) # Ash Wednesday self.assertIn(date(2020, 4, 10), holidays) # good friday self.assertIn(date(2020, 4, 13), holidays) # easter monday self.assertIn(date(2020, 5, 18), holidays) # Discovery Day self.assertIn(date(2020, 6, 15), holidays) # Queen's Birthday self.assertIn(date(2020, 7, 6), holidays) # Constitution Day self.assertIn(date(2020, 11, 9), holidays) # Remembrance Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # Boxing Day class CroatiaTest(GenericCalendarTest): cal_class = Croatia def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Year's Day self.assertIn(date(2016, 1, 6), holidays) # Epiphany / Bogojavljenje self.assertIn(date(2016, 3, 27), holidays) # Easter Sunday self.assertIn(date(2016, 3, 28), holidays) # Easter Monday self.assertIn(date(2016, 5, 1), holidays) # Intl Workers' Day self.assertIn(date(2016, 5, 26), holidays) # Corpus Christi / Tijelovo self.assertIn(date(2016, 6, 22), holidays) # Anti-Fascist Day self.assertIn(date(2016, 6, 25), holidays) # Statehood Day self.assertIn(date(2016, 8, 5), holidays) # Victory & Homeland Thanks self.assertIn(date(2016, 8, 15), holidays) # Assumption of Mary self.assertIn(date(2016, 10, 8), holidays) # Independence Day Dan neov self.assertIn(date(2016, 11, 1), holidays) # All Saints' Day Dan svih self.assertIn(date(2016, 12, 25), holidays) # Christmas Božić self.assertIn(date(2016, 12, 26), holidays) # St. Stephen's Day Prvi d def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year's Day self.assertIn(date(2020, 1, 6), holidays) # Epiphany / Bogojavljenje self.assertIn(date(2020, 4, 12), holidays) # Easter Sunday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 30), holidays) # Statehood day self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 6, 22), holidays) # Anti-Fascist Day # Victory & Homeland Thanksgiving self.assertIn(date(2020, 8, 5), holidays) self.assertIn(date(2020, 8, 15), holidays) # Assumption of Mary self.assertIn(date(2020, 11, 1), holidays) # All Saints' Day self.assertIn(date(2020, 11, 18), holidays) # Remembrance Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen def test_statehood_day(self): holidays_2019 = self.cal.holidays_set(2019) holidays_2020 = self.cal.holidays_set(2020) # Statehood day was a holiday on June 25th until 2020 self.assertIn(date(2019, 6, 25), holidays_2019) self.assertNotIn(date(2020, 6, 25), holidays_2020) # Statehood day as of 2020 happens on May 30th self.assertNotIn(date(2019, 5, 30), holidays_2019) self.assertIn(date(2020, 5, 30), holidays_2020) def test_independance_day(self): # Independence Day was a holiday until 2020 holidays_2019 = self.cal.holidays_set(2019) self.assertIn(date(2019, 10, 8), holidays_2019) holidays_2020 = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 10, 8), holidays_2020) def test_remembrance_day(self): # Remembrance Day was introduced as of 2020 holidays_2018 = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 11, 18), holidays_2018) holidays_2019 = self.cal.holidays_set(2019) self.assertNotIn(date(2019, 11, 18), holidays_2019) holidays_2020 = self.cal.holidays_set(2020) self.assertIn(date(2020, 11, 18), holidays_2020) def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "International Workers' Day") class CyprusTest(GenericCalendarTest): cal_class = Cyprus def test_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # New Year's Day self.assertIn(date(2017, 1, 6), holidays) # Epiphany self.assertIn(date(2017, 2, 27), holidays) # Green Monday self.assertIn(date(2017, 3, 25), holidays) # Greek Independence Day self.assertIn(date(2017, 4, 1), holidays) # Cyprus National Holiday self.assertIn(date(2017, 4, 14), holidays) # Good Friday (Orthodox) self.assertIn(date(2017, 4, 17), holidays) # Easter Monday (Orthodox) self.assertIn(date(2017, 4, 18), holidays) # Easter Tues banks only self.assertIn(date(2017, 5, 1), holidays) # Labour Day/May Day self.assertIn(date(2017, 6, 5), holidays) # Orthodox Pentecost Mon self.assertIn(date(2017, 7, 15), holidays) # Assumption self.assertIn(date(2017, 10, 1), holidays) # Cyprus Independence Day self.assertIn(date(2017, 10, 28), holidays) # Ochi Day self.assertIn(date(2017, 12, 25), holidays) # Christmas Day self.assertIn(date(2017, 12, 26), holidays) # Boxing Day class CzechRepublicTest(GenericCalendarTest): cal_class = CzechRepublic def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 4, 1), holidays) self.assertIn(date(2013, 5, 1), holidays) self.assertIn(date(2013, 5, 8), holidays) self.assertIn(date(2013, 7, 5), holidays) self.assertIn(date(2013, 7, 6), holidays) self.assertIn(date(2013, 9, 28), holidays) self.assertIn(date(2013, 10, 28), holidays) self.assertIn(date(2013, 11, 17), holidays) self.assertIn(date(2013, 12, 24), holidays) self.assertIn(date(2013, 12, 25), holidays) self.assertIn(date(2013, 12, 26), holidays) def test_year_good_friday(self): # Good Friday not yet a holiday before 2016 holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 4, 3), holidays) # Good friday will be a holiday as of 2016 holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 3, 25), holidays) class DenmarkTest(GenericCalendarTest): cal_class = Denmark def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # nytaarsdag self.assertIn(date(2015, 4, 2), holidays) # skaertaarsdag self.assertIn(date(2015, 4, 3), holidays) # langfredag self.assertIn(date(2015, 4, 5), holidays) # paaskedag self.assertIn(date(2015, 4, 6), holidays) # 2. paaskedag self.assertIn(date(2015, 5, 1), holidays) # st bededag self.assertIn(date(2015, 5, 14), holidays) # kristi himmelfart self.assertIn(date(2015, 5, 24), holidays) # pinsedag self.assertIn(date(2015, 5, 25), holidays) # 2. pinsedag self.assertIn(date(2015, 12, 24), holidays) # juleaftensdag self.assertIn(date(2015, 12, 25), holidays) # juledag self.assertIn(date(2015, 12, 26), holidays) # 2. juledag class SlovakiaTest(GenericCalendarTest): cal_class = Slovakia def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 1, 6), holidays) self.assertIn(date(2013, 3, 29), holidays) self.assertIn(date(2013, 4, 1), holidays) self.assertIn(date(2013, 5, 1), holidays) self.assertIn(date(2013, 5, 8), holidays) self.assertIn(date(2013, 7, 5), holidays) self.assertIn(date(2013, 8, 29), holidays) self.assertIn(date(2013, 9, 1), holidays) self.assertIn(date(2013, 9, 15), holidays) self.assertIn(date(2013, 11, 1), holidays) self.assertIn(date(2013, 11, 17), holidays) self.assertIn(date(2013, 12, 24), holidays) self.assertIn(date(2013, 12, 25), holidays) self.assertIn(date(2013, 12, 26), holidays) def test_removed_duplicate(self): holidays = self.cal.holidays(2017) counter = Counter(day for day, label in holidays) # Only one "all saints" self.assertEqual(counter[date(2017, 11, 1)], 1) # Only one "XMas eve" self.assertEqual(counter[date(2017, 12, 24)], 1) # De-duplicate, XMas day was configured twice. # Refs #205. self.assertEqual(counter[date(2017, 12, 25)], 1) # Only one St Stephen self.assertEqual(counter[date(2017, 12, 25)], 1) class SwedenTest(GenericCalendarTest): cal_class = Sweden def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 1, 6), holidays) # epiphany self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # may day self.assertIn(date(2013, 5, 9), holidays) # ascension self.assertIn(date(2013, 5, 19), holidays) # pentecost self.assertIn(date(2013, 6, 6), holidays) # national day self.assertIn(date(2013, 6, 21), holidays) # midsummer eve self.assertIn(date(2013, 6, 22), holidays) # midsummer day self.assertIn(date(2013, 11, 2), holidays) # all saints self.assertIn(date(2013, 12, 24), holidays) # xmas eve self.assertIn(date(2013, 12, 25), holidays) # xmas day self.assertIn(date(2013, 12, 26), holidays) # second day of xmas self.assertIn(date(2013, 12, 31), holidays) # new year's eve def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) # new year self.assertIn(date(2014, 1, 6), holidays) # epiphany self.assertIn(date(2014, 4, 18), holidays) # good friday self.assertIn(date(2014, 4, 20), holidays) # easter sunday self.assertIn(date(2014, 4, 21), holidays) # easter monday self.assertIn(date(2014, 5, 1), holidays) # may day self.assertIn(date(2014, 5, 29), holidays) # ascension self.assertIn(date(2014, 6, 6), holidays) # national day self.assertIn(date(2014, 6, 8), holidays) # pentecost self.assertIn(date(2014, 6, 20), holidays) # midsummer eve self.assertIn(date(2014, 6, 21), holidays) # midsummer day self.assertIn(date(2014, 11, 1), holidays) # all saints self.assertIn(date(2014, 12, 24), holidays) # xmas eve self.assertIn(date(2014, 12, 25), holidays) # xmas day self.assertIn(date(2014, 12, 26), holidays) # second day of xmas self.assertIn(date(2014, 12, 31), holidays) # new year's eve def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # new year self.assertIn(date(2015, 1, 6), holidays) # epiphany self.assertIn(date(2015, 4, 3), holidays) # good friday self.assertIn(date(2015, 4, 5), holidays) # easter sunday self.assertIn(date(2015, 4, 6), holidays) # easter monday self.assertIn(date(2015, 5, 1), holidays) # may day self.assertIn(date(2015, 5, 14), holidays) # ascension self.assertIn(date(2015, 5, 24), holidays) # pentecost self.assertIn(date(2015, 6, 6), holidays) # national day self.assertIn(date(2015, 6, 19), holidays) # midsummer eve self.assertIn(date(2015, 6, 20), holidays) # midsummer day self.assertIn(date(2015, 10, 31), holidays) # all saints self.assertIn(date(2015, 12, 24), holidays) # xmas eve self.assertIn(date(2015, 12, 25), holidays) # xmas day self.assertIn(date(2015, 12, 26), holidays) # second day of xmas self.assertIn(date(2015, 12, 31), holidays) # new year's eve def test_pentecost(self): "Pentecost is designated on May 24, 2015" pentecost, = ( holiday for holiday in self.cal.holidays_set(2015) if holiday.name == 'Pentecost' ) assert pentecost == date(2015, 5, 24) class FinlandTest(GenericCalendarTest): cal_class = Finland def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 1, 6), holidays) # epiphany self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # may day self.assertIn(date(2013, 5, 9), holidays) # ascension self.assertIn(date(2013, 5, 19), holidays) # pentecost self.assertIn(date(2013, 6, 21), holidays) # midsummer eve self.assertIn(date(2013, 6, 22), holidays) # midsummer day self.assertIn(date(2013, 11, 2), holidays) # all saints (special) self.assertIn(date(2013, 12, 6), holidays) # Independence day self.assertIn(date(2013, 12, 24), holidays) # XMas eve self.assertIn(date(2013, 12, 25), holidays) # XMas self.assertIn(date(2013, 12, 26), holidays) # St Stephens def test_year_2014(self): # testing the special rule variable holidays holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 20), holidays) # midsummer eve self.assertIn(date(2014, 6, 21), holidays) # midsummer day self.assertIn(date(2014, 11, 1), holidays) # all saints (special) def test_holidays_not_shifted(self): """ Holidays should not be shifted for Finland. """ observed = self.cal.observed_holidays(2014) self.assertIn(date(2014, 12, 6), observed) self.assertTrue(self.cal.is_working_day(date(2014, 12, 8))) class FranceTest(GenericCalendarTest): cal_class = France def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 4, 1), holidays) # easter self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 5, 8), holidays) # 39-45 self.assertIn(date(2013, 5, 9), holidays) # Ascension self.assertIn(date(2013, 5, 20), holidays) # Pentecote self.assertIn(date(2013, 7, 14), holidays) # Nation day self.assertIn(date(2013, 8, 15), holidays) # Assomption self.assertIn(date(2013, 11, 1), holidays) # Toussaint self.assertIn(date(2013, 11, 11), holidays) # Armistice self.assertIn(date(2013, 12, 25), holidays) # Christmas def test_working_days(self): self.assertFalse(self.cal.is_working_day(date(2013, 1, 1))) # holiday self.assertFalse(self.cal.is_working_day(date(2013, 1, 5))) # saturday self.assertFalse(self.cal.is_working_day(date(2013, 1, 6))) # sunday self.assertTrue(self.cal.is_working_day(date(2013, 1, 7))) # monday def test_business_days_computations(self): day = date(2013, 10, 30) self.assertEqual( self.cal.add_working_days(day, 0), date(2013, 10, 30)) self.assertEqual( self.cal.add_working_days(day, 1), date(2013, 10, 31)) self.assertEqual(self.cal.add_working_days(day, 2), date(2013, 11, 4)) self.assertEqual(self.cal.add_working_days(day, 3), date(2013, 11, 5)) class FranceAlsaceMoselleTest(FranceTest): cal_class = FranceAlsaceMoselle def test_year_2013(self): super().test_year_2013() holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 29), holidays) # Good friday self.assertIn(date(2013, 12, 26), holidays) # Boxing day def test_working_days(self): super().test_working_days() def test_business_days_computations(self): super().test_business_days_computations() class GeorgiaTest(GenericCalendarTest): cal_class = Georgia def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Year self.assertIn(date(2016, 1, 2), holidays) # Second day of the New Year self.assertIn(date(2016, 1, 7), holidays) # Orthodox Christmas self.assertIn(date(2016, 1, 19), holidays) # Orthodox Epiphany self.assertIn(date(2016, 3, 3), holidays) # Mother's Day self.assertIn(date(2016, 3, 8), holidays) # International Women's Day self.assertIn(date(2016, 4, 9), holidays) # Day of National Unity self.assertIn(date(2016, 4, 29), holidays) # Orthodox Good Friday self.assertIn(date(2016, 4, 30), holidays) # Great Saturday self.assertIn(date(2016, 5, 1), holidays) # Orthodox Easter Day self.assertIn(date(2016, 5, 2), holidays) # Orthodox Easter Monday self.assertIn(date(2016, 5, 9), holidays) # Day of victory self.assertIn(date(2016, 5, 12), holidays) # St Andrew's day self.assertIn(date(2016, 5, 26), holidays) # Independence Day self.assertIn(date(2016, 8, 28), holidays) # St Mary's Day self.assertIn(date(2016, 10, 14), holidays) # Day of Svetitskovloba self.assertIn(date(2016, 11, 23), holidays) # St George's day def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 2), holidays) # Second day of the New Year self.assertIn(date(2020, 1, 7), holidays) # Orthodox Christmas self.assertIn(date(2020, 1, 19), holidays) # Orthodox Epiphany self.assertIn(date(2020, 3, 3), holidays) # Mother's Day self.assertIn(date(2020, 3, 8), holidays) # International Women's Day self.assertIn(date(2020, 4, 9), holidays) # Day of National Unity self.assertIn(date(2020, 4, 17), holidays) # Orthodox Good Friday self.assertIn(date(2020, 4, 18), holidays) # Great Saturday self.assertIn(date(2020, 4, 19), holidays) # Orthodox Easter Day self.assertIn(date(2020, 4, 20), holidays) # Orthodox Easter Monday self.assertIn(date(2020, 5, 9), holidays) # Day of victory self.assertIn(date(2020, 5, 12), holidays) # St Andrew's Day self.assertIn(date(2020, 5, 26), holidays) # Independence Day self.assertIn(date(2020, 8, 28), holidays) # St Mary's Day self.assertIn(date(2020, 10, 14), holidays) # Day of Svetitskovloba self.assertIn(date(2020, 11, 23), holidays) # St George's Day def test_no_labor_day(self): holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 5, 1), holidays) def test_no_christmas(self): holidays = self.cal.holidays_set(2016) self.assertNotIn(date(2016, 12, 24), holidays) self.assertNotIn(date(2016, 12, 25), holidays) holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 12, 24), holidays) self.assertNotIn(date(2020, 12, 25), holidays) class GreeceTest(GenericCalendarTest): cal_class = Greece def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 1, 6), holidays) # epiphany self.assertIn(date(2013, 3, 18), holidays) # Clean monday # Annunciation & Independence day self.assertIn(date(2013, 3, 25), holidays) self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 5, 3), holidays) # good friday self.assertIn(date(2013, 5, 5), holidays) # easter self.assertIn(date(2013, 5, 6), holidays) # easter monday self.assertIn(date(2013, 6, 23), holidays) # pentecost sunday self.assertIn(date(2013, 6, 24), holidays) # whit monday self.assertIn(date(2013, 8, 15), holidays) # Assumption self.assertIn(date(2013, 10, 28), holidays) # Ochi Day self.assertIn(date(2013, 12, 25), holidays) # XMas self.assertIn(date(2013, 12, 26), holidays) # Glorifying mother of God def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # new year self.assertIn(date(2020, 1, 6), holidays) # epiphany self.assertIn(date(2020, 3, 2), holidays) # Clean monday # Annunciation & Independence day self.assertIn(date(2020, 3, 25), holidays) self.assertIn(date(2020, 4, 17), holidays) # good friday self.assertIn(date(2020, 4, 19), holidays) # easter self.assertIn(date(2020, 4, 20), holidays) # easter monday self.assertIn(date(2020, 5, 1), holidays) # labour day self.assertIn(date(2020, 6, 7), holidays) # pentecost sunday self.assertIn(date(2020, 6, 8), holidays) # whit monday self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 10, 28), holidays) # Ochi Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # Glorifying mother of God def test_no_orthodox_christmas(self): # This calendar is an Orthodox calendar, but there's no Jan XMas holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 1, 7), holidays) class HungaryTest(GenericCalendarTest): cal_class = Hungary def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 3, 15), holidays) # national day self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # Labour day self.assertIn(date(2013, 5, 19), holidays) # Whit sunday self.assertIn(date(2013, 5, 20), holidays) # Whit monday self.assertIn(date(2013, 8, 20), holidays) # St Stephen's day self.assertIn(date(2013, 10, 23), holidays) # national day (again?) self.assertIn(date(2013, 11, 1), holidays) # all saints self.assertIn(date(2013, 12, 25), holidays) # XMas self.assertIn(date(2013, 12, 26), holidays) # Second day of XMas def test_year_good_friday(self): # Since the year 2017, Good Friday is a non-working day un Hungary # Refs #203 holidays = self.cal.holidays_set(2016) good_friday_2016 = date(2016, 3, 25) self.assertNotIn(good_friday_2016, holidays) # 2017 holidays = self.cal.holidays_set(2017) good_friday_2017 = date(2017, 4, 14) self.assertIn(good_friday_2017, holidays) class MaltaTest(GenericCalendarTest): """Rollover rules changed in 2005""" cal_class = Malta def test_year_2017(self): holidays = self.cal.holidays_set(2017) # National Holidays self.assertIn(date(2017, 3, 31), holidays) # Jum il-Ħelsien self.assertIn(date(2017, 6, 7), holidays) # Sette Giugno self.assertIn(date(2017, 9, 8), holidays) # Jum il-Vitorja self.assertIn(date(2017, 9, 21), holidays) # Jum l-Indipendenza self.assertIn(date(2017, 12, 13), holidays) # Jum ir-Repubblika # Public Holidays self.assertIn(date(2017, 1, 1), holidays) # L-Ewwel tas-Sena self.assertIn(date(2017, 2, 10), holidays) # Nawfraġju ta' San Pawl self.assertIn(date(2017, 3, 19), holidays) # San Ġużepp self.assertIn(date(2017, 4, 14), holidays) # Il-Ġimgħa l-Kbira self.assertIn(date(2017, 5, 1), holidays) # Jum il-Ħaddiem self.assertIn(date(2017, 6, 29), holidays) # L-Imnarja self.assertIn(date(2017, 8, 15), holidays) # Santa Marija self.assertIn(date(2017, 12, 8), holidays) # Il-Kunċizzjoni self.assertIn(date(2017, 12, 25), holidays) # Il-Milied def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Worker's Day") class MonacoTest(GenericCalendarTest): cal_class = Monaco def test_year_2020(self): holidays = self.cal.holidays_set(2020) # National Holidays self.assertIn(date(2020, 1, 1), holidays) # New Year's Day self.assertIn(date(2020, 1, 27), holidays) # Saint Dévote's Day self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension Day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 15), holidays) # Assumption Day self.assertIn(date(2020, 11, 1), holidays) # All Saints' Day self.assertIn(date(2020, 11, 19), holidays) # Sovereign Prince's Day self.assertIn(date(2020, 12, 8), holidays) # Conception Day self.assertIn(date(2020, 12, 25), holidays) # Christmas Day def test_year_2018(self): holidays = self.cal.holidays_set(2018) # National Holidays self.assertIn(date(2018, 1, 1), holidays) # New Year's Day self.assertIn(date(2018, 1, 27), holidays) # Saint Dévote's Day self.assertIn(date(2018, 4, 2), holidays) # Easter Monday self.assertIn(date(2018, 5, 1), holidays) # Labour Day self.assertIn(date(2018, 5, 10), holidays) # Ascension Day self.assertIn(date(2018, 5, 21), holidays) # Whit Monday self.assertIn(date(2018, 5, 31), holidays) # Corpus Christi self.assertIn(date(2018, 8, 15), holidays) # Assumption Day self.assertIn(date(2018, 11, 1), holidays) # All Saints' Day self.assertIn(date(2018, 11, 19), holidays) # Sovereign Prince's Day self.assertIn(date(2018, 12, 8), holidays) # Conception Day self.assertIn(date(2018, 12, 25), holidays) # Christmas Day class NorwayTest(GenericCalendarTest): cal_class = Norway def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 3, 28), holidays) # maundy thursday self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 1), holidays) # labour day self.assertIn(date(2013, 5, 17), holidays) # constitution day self.assertIn(date(2013, 5, 9), holidays) # Ascension self.assertIn(date(2013, 5, 19), holidays) # Pentecost self.assertIn(date(2013, 5, 20), holidays) # Whit monday self.assertIn(date(2013, 12, 25), holidays) # Xmas self.assertIn(date(2013, 12, 26), holidays) # St Stephens class PolandTest(GenericCalendarTest): cal_class = Poland def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year self.assertIn(date(2013, 1, 6), holidays) # Trzech Kroli self.assertIn(date(2013, 3, 31), holidays) # Easter Sunday self.assertIn(date(2013, 4, 1), holidays) # Easter Monday self.assertIn(date(2013, 5, 1), holidays) # Labor Day self.assertIn(date(2013, 5, 3), holidays) # Constitution Day self.assertIn(date(2013, 5, 19), holidays) # Pentecost self.assertIn(date(2013, 5, 30), holidays) # Corpus Christi self.assertIn(date(2013, 8, 15), holidays) # Assumption self.assertIn(date(2013, 11, 1), holidays) # All Saints' Day self.assertIn(date(2013, 11, 11), holidays) # Independence Day self.assertIn(date(2013, 12, 25), holidays) # Christmas Day self.assertIn(date(2013, 12, 26), holidays) # Boxing Day def test_shift_2016(self): # Poland does not roll christmas and boxing day holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 12, 25), holidays) # Christmas - Sunday self.assertIn(date(2016, 12, 26), holidays) # Boxing day - Monday self.assertNotIn(date(2016, 12, 27), holidays) # Christmas shift class IcelandTest(GenericCalendarTest): cal_class = Iceland def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertIn(date(2013, 3, 28), holidays) self.assertIn(date(2013, 3, 29), holidays) self.assertIn(date(2013, 4, 1), holidays) self.assertIn(date(2013, 4, 25), holidays) self.assertIn(date(2013, 5, 1), holidays) self.assertIn(date(2013, 5, 9), holidays) self.assertIn(date(2013, 5, 20), holidays) self.assertIn(date(2013, 6, 17), holidays) self.assertIn(date(2013, 8, 5), holidays) self.assertIn(date(2013, 12, 24), holidays) self.assertIn(date(2013, 12, 25), holidays) self.assertIn(date(2013, 12, 26), holidays) self.assertIn(date(2013, 12, 31), holidays) class IrelandTest(GenericCalendarTest): cal_class = Ireland def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # Tue New Year's Day self.assertIn(date(2013, 3, 17), holidays) # Sun St Patricks day self.assertIn(date(2013, 3, 18), holidays) # Mon St Patricks shift self.assertIn(date(2013, 4, 1), holidays) # Mon Easter Monday self.assertIn(date(2013, 5, 6), holidays) # Mon May day self.assertIn(date(2013, 6, 3), holidays) # Mon June Holiday self.assertIn(date(2013, 8, 5), holidays) # Mon August Holiday self.assertIn(date(2013, 10, 28), holidays) # Mon October Holiday self.assertIn(date(2013, 12, 25), holidays) # Wed Christmas self.assertIn(date(2013, 12, 26), holidays) # Thu St Stepehen's def test_shift_2012(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 1), holidays) # new year day observed = self.cal.observed_holidays(2012) self.assertIn(date(2012, 1, 2), observed) # new year day shift def test_shift_2011(self): holidays = self.cal.holidays_set(2011) self.assertIn(date(2011, 12, 25), holidays) # Christmas it's sunday self.assertIn(date(2011, 12, 26), holidays) # Xmas day shift self.assertIn(date(2011, 12, 27), holidays) # St Stephen's day shift def test_shift_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 12, 25), holidays) # Christmas it's friday self.assertIn(date(2015, 12, 26), holidays) # St. Stephen's day Sat self.assertIn(date(2015, 12, 28), holidays) # St. Stephen's day shift def test_whit_mon(self): holidays_1972 = self.cal.holidays_set(1972) holidays_1973 = self.cal.holidays_set(1973) # holidays_1974 = self.cal.holidays_set(1974) Overlaps with June Hol holidays_1975 = self.cal.holidays_set(1975) self.assertIn(date(1972, 5, 22), holidays_1972) # Whit Monday self.assertIn(date(1973, 6, 11), holidays_1973) # self.assertNotIn(date(1974, 6, 3), holidays_1974) # Overlaps Jun Hol self.assertNotIn(date(1975, 5, 19), holidays_1975) # No Whit Monday def test_may_day(self): holidays_1993 = self.cal.holidays_set(1993) holidays_1994 = self.cal.holidays_set(1994) holidays_1995 = self.cal.holidays_set(1995) self.assertNotIn(date(1993, 5, 1), holidays_1993) # No May Day self.assertIn(date(1994, 5, 2), holidays_1994) # May Day self.assertIn(date(1995, 5, 1), holidays_1995) def test_october_holiday(self): holidays_1976 = self.cal.holidays_set(1976) holidays_1977 = self.cal.holidays_set(1977) holidays_1978 = self.cal.holidays_set(1978) self.assertNotIn(date(1976, 10, 25), holidays_1976) # No October Hol self.assertIn(date(1977, 10, 31), holidays_1977) # October Hol self.assertIn(date(1978, 10, 30), holidays_1978) class ItalyTest(GenericCalendarTest): cal_class = Italy def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new years day self.assertIn(date(2013, 1, 6), holidays) # Epiphany self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 4, 25), holidays) # liberation day self.assertIn(date(2013, 5, 1), holidays) # workers day self.assertIn(date(2013, 6, 2), holidays) # Republic day self.assertIn(date(2013, 8, 15), holidays) # Assumption self.assertIn(date(2013, 11, 1), holidays) # all saints self.assertIn(date(2013, 12, 8), holidays) # immaculate Conception self.assertIn(date(2013, 12, 25), holidays) # christmas self.assertIn(date(2013, 12, 26), holidays) # San Stefano def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "International Workers' Day") class LatviaTest(GenericCalendarTest): cal_class = Latvia def test_year_2017(self): """ https://www.bank.lv/en/about-us/public-holidays-in-latvia """ holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # New Year's Day self.assertIn(date(2017, 4, 14), holidays) # Easter 14 and 17 april self.assertIn(date(2017, 4, 16), holidays) # Easter 14 and 17 april self.assertIn(date(2017, 4, 17), holidays) # Easter 14 and 17 april self.assertIn(date(2017, 5, 1), holidays) # Labour Day, C self.assertIn(date(2017, 5, 4), holidays) # Restoration of Independe self.assertIn(date(2017, 6, 23), holidays) # Midsummer Day self.assertIn(date(2017, 6, 24), holidays) # St. John's Day self.assertIn(date(2017, 11, 18), holidays) # Proclamation self.assertIn(date(2017, 11, 20), holidays) # Proclamation Observed self.assertIn(date(2017, 12, 24), holidays) # Christmas self.assertIn(date(2017, 12, 25), holidays) # Christmas self.assertIn(date(2017, 12, 26), holidays) # Christmas self.assertIn(date(2017, 12, 31), holidays) # New Year's Eve def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 5, 6), holidays) # Restoration Day Observed class LuxembourgTest(GenericCalendarTest): cal_class = Luxembourg def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # new year self.assertIn(date(2016, 3, 28), holidays) # easter self.assertIn(date(2016, 5, 1), holidays) # labour day self.assertIn(date(2016, 5, 5), holidays) # Ascension self.assertIn(date(2016, 5, 16), holidays) # Pentecote self.assertIn(date(2016, 6, 23), holidays) # Luxembourg National Day self.assertIn(date(2016, 8, 15), holidays) # Assomption self.assertIn(date(2016, 11, 1), holidays) # Toussaint self.assertIn(date(2016, 12, 25), holidays) # Christmas self.assertIn(date(2016, 12, 26), holidays) # St. Stephen´s Day self.assertNotIn(date(2016, 5, 9), holidays) # Europe Day (>=2019) def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 5, 9), holidays) # Europe Day (>=2019) class NetherlandsTest(GenericCalendarTest): cal_class = Netherlands def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # New Year self.assertIn(date(2015, 4, 3), holidays) # Good friday self.assertIn(date(2015, 4, 5), holidays) # Easter Sunday self.assertIn(date(2015, 4, 6), holidays) # Easter Monday self.assertIn(date(2015, 4, 27), holidays) # King's Day self.assertIn(date(2015, 5, 5), holidays) # Liberation Day self.assertIn(date(2015, 5, 14), holidays) # Ascension self.assertIn(date(2015, 5, 24), holidays) # whit sunday self.assertIn(date(2015, 5, 25), holidays) # whit monday self.assertIn(date(2015, 12, 25), holidays) # Christmas self.assertIn(date(2015, 12, 26), holidays) # St. Stephen´s Day def test_king_day_2014(self): # As of 2014, King's Day replaces Queen's Day. # It's normally happening on April 27th, except when it's on SUN queen_day = date(2014, 4, 30) real_king_day = date(2014, 4, 27) king_day = date(2014, 4, 26) holidays = dict(self.cal.holidays(2014)) self.assertNotIn(queen_day, holidays) self.assertNotIn(real_king_day, holidays) self.assertIn(king_day, holidays) self.assertEqual(holidays[king_day], "King's day") def test_king_day_2020(self): # Regular King's day king_day = date(2020, 4, 27) holidays = dict(self.cal.holidays(2020)) self.assertIn(king_day, holidays) self.assertEqual(holidays[king_day], "King's day") def test_king_day_2025(self): # In 2025, it's shifted to the 26th, because it happens on SUN holidays = self.cal.holidays_set(2025) real_king_day = date(2025, 4, 27) king_day = date(2025, 4, 26) self.assertNotIn(real_king_day, holidays) self.assertIn(king_day, holidays) def test_queen_day(self): # In 1990 Queen's day was on 30 April. So it was until 2013. queen_day = date(1990, 4, 30) holidays = dict(self.cal.holidays(1990)) self.assertIn(queen_day, holidays) # Check for label self.assertEqual(holidays[queen_day], "Queen's day") # Check in 2010 queen_day = date(2010, 4, 30) holidays = dict(self.cal.holidays(2010)) self.assertIn(queen_day, holidays) # Check for label self.assertEqual(holidays[queen_day], "Queen's day") # No more in 2014 queen_day = date(2014, 4, 30) holidays = self.cal.holidays_set(2014) self.assertNotIn(queen_day, holidays) def test_queen_day_on_sunday(self): # On April 30th, 2006 Queen's day happened on SUN. queen_day = date(2006, 4, 29) holidays = dict(self.cal.holidays(2006)) # The regular holiday self.assertNotIn(date(2006, 4, 30), holidays) # It's shifted to the previous day self.assertIn(queen_day, holidays) self.assertEqual(holidays[queen_day], "Queen's day") def test_new_years_eve(self): # For some reason, the new year's eve was added to the list of fixed # holidays. It appears it's not a holiday holidays = self.cal.holidays_set(2016) self.assertNotIn(date(2016, 12, 31), holidays) class NetherlandsWithSchoolHolidaysWithInvalidRegionTest(TestCase): def test_instanciate_invalid_region(self): with self.assertRaises(ValueError) as cm: NetherlandsWithSchoolHolidays(region="east") assert "Set region" in str(cm.exception) with self.assertRaises(ValueError) as cm: NetherlandsWithSchoolHolidays(region="") assert "Set region" in str(cm.exception) def test_instanciate_no_region(self): with self.assertRaises(TypeError) as cm: NetherlandsWithSchoolHolidays() assert "missing 1 required positional argument" in str(cm.exception) class NetherlandsWithSchoolHolidaysInvalidRanges(TestCase): def test_spring_holidays_invalid_range(self): max_year = max(SPRING_HOLIDAYS_EARLY_REGIONS) calendar = NetherlandsWithSchoolHolidays(region="north") with self.assertRaises(NotImplementedError): calendar.get_spring_holidays(max_year + 1) def test_summer_early_holidays_invalid_range(self): max_year = max(SUMMER_HOLIDAYS_EARLY_REGIONS) calendar = NetherlandsWithSchoolHolidays(region="north") with self.assertRaises(NotImplementedError): calendar.get_summer_holidays(max_year + 1) def test_summer_late_holidays_invalid_range(self): max_year = max(SUMMER_HOLIDAYS_LATE_REGIONS) calendar = NetherlandsWithSchoolHolidays(region="north") with self.assertRaises(NotImplementedError): calendar.get_summer_holidays(max_year + 1) class NetherlandsNorthWithSchoolHolidaysTest(GenericCalendarTest): cal_class = NetherlandsWithSchoolHolidays kwargs = dict(region="north") def test_year_2010(self): with self.assertRaises(NotImplementedError): dict(self.cal.holidays(2010)) def test_year_2020(self): year = 2020 christmas_holiday_end = date(2020, 1, 5) spring_holiday_start = date(2020, 2, 15) may_holiday_start = date(2020, 4, 25) summer_holiday_start = date(2020, 7, 4) fall_holiday_start = date(2020, 10, 10) christmas_holiday_start = date(2020, 12, 19) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def test_year_2021(self): year = 2021 christmas_holiday_end = date(2021, 1, 3) spring_holiday_start = date(2021, 2, 20) may_holiday_start = date(2021, 5, 1) summer_holiday_start = date(2021, 7, 10) fall_holiday_start = date(2021, 10, 16) christmas_holiday_start = date(2021, 12, 25) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def _test_school_holidays( self, year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ): holidays = {} for h in self.cal.holidays(year): holidays.setdefault(h[0], []).append(h[1]) for d in range(christmas_holiday_end.day): self.assertIn( "Christmas holiday", holidays[christmas_holiday_end - timedelta(days=d)], ) for d in range(9): self.assertIn( "Spring holiday", holidays[spring_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "May holiday", holidays[may_holiday_start + timedelta(days=d)], ) for d in range(44): self.assertIn( "Summer holiday", holidays[summer_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "Fall holiday", holidays[fall_holiday_start + timedelta(days=d)], ) for d in range(31 - christmas_holiday_start.day + 1): self.assertIn( "Christmas holiday", holidays[christmas_holiday_start + timedelta(days=d)], ) def test_may_holidays_exceptions(self): # In 2017, May holidays started on week 17 instead of 18 # First, make sure we have a coherent date for 2021 may_holidays_2021 = self.cal.get_may_holidays(2021) start_2021 = may_holidays_2021[0][0] self.assertEqual( start_2021, # Preceding SAT self.cal.get_iso_week_date(2021, 18 - 1, ISO_SAT) ) # Then, get the start date for 2017 may_holidays_2017 = self.cal.get_may_holidays(2017) start_2017 = may_holidays_2017[0][0] self.assertEqual( start_2017, # Preceding SAT self.cal.get_iso_week_date(2017, 17 - 1, ISO_SAT) ) def test_fall_holidays_exceptions(self): # In 2024, May holidays start on week 44 instead of 43 # First, make sure we have a coherent date for 2019 # (using 2019 to avoid being in FALL_HOLIDAYS_EARLY_REGIONS) fall_holidays_2019 = self.cal.get_fall_holidays(2019) start_2019 = fall_holidays_2019[0][0] self.assertEqual( start_2019, # Preceding SAT self.cal.get_iso_week_date(2019, 43 - 1, ISO_SAT) ) # Then, get the start date for 2024 fall_holidays_2024 = self.cal.get_fall_holidays(2024) start_2024 = fall_holidays_2024[0][0] self.assertEqual( start_2024, # Preceding SAT self.cal.get_iso_week_date(2024, 44 - 1, ISO_SAT) ) class NetherlandsMiddleWithSchoolHolidaysTest(GenericCalendarTest): cal_class = NetherlandsWithSchoolHolidays kwargs = dict(region="middle") def test_year_2010(self): with self.assertRaises(NotImplementedError): dict(self.cal.holidays(2010)) def test_year_2020(self): year = 2020 christmas_holiday_end = date(2020, 1, 5) spring_holiday_start = date(2020, 2, 22) may_holiday_start = date(2020, 4, 25) summer_holiday_start = date(2020, 7, 18) fall_holiday_start = date(2020, 10, 17) christmas_holiday_start = date(2020, 12, 19) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def test_year_2021(self): year = 2021 christmas_holiday_end = date(2021, 1, 3) spring_holiday_start = date(2021, 2, 20) may_holiday_start = date(2021, 5, 1) summer_holiday_start = date(2021, 7, 17) fall_holiday_start = date(2021, 10, 16) christmas_holiday_start = date(2021, 12, 25) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def _test_school_holidays( self, year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ): holidays = {} for h in self.cal.holidays(year): holidays.setdefault(h[0], []).append(h[1]) for d in range(christmas_holiday_end.day): self.assertIn( "Christmas holiday", holidays[christmas_holiday_end - timedelta(days=d)], ) for d in range(9): self.assertIn( "Spring holiday", holidays[spring_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "May holiday", holidays[may_holiday_start + timedelta(days=d)], ) for d in range(44): self.assertIn( "Summer holiday", holidays[summer_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "Fall holiday", holidays[fall_holiday_start + timedelta(days=d)], ) for d in range(31 - christmas_holiday_start.day + 1): self.assertIn( "Christmas holiday", holidays[christmas_holiday_start + timedelta(days=d)], ) class NetherlandsSouthWithSchoolHolidaysTest(GenericCalendarTest): cal_class = NetherlandsWithSchoolHolidays kwargs = dict(region="south") def test_year_2010(self): with self.assertRaises(NotImplementedError): dict(self.cal.holidays(2010)) def test_year_2020(self): year = 2020 christmas_holiday_end = date(2020, 1, 5) spring_holiday_start = date(2020, 2, 22) may_holiday_start = date(2020, 4, 25) summer_holiday_start = date(2020, 7, 11) fall_holiday_start = date(2020, 10, 17) christmas_holiday_start = date(2020, 12, 19) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def test_year_2021(self): year = 2021 christmas_holiday_end = date(2021, 1, 3) spring_holiday_start = date(2021, 2, 13) may_holiday_start = date(2021, 5, 1) summer_holiday_start = date(2021, 7, 24) fall_holiday_start = date(2021, 10, 23) christmas_holiday_start = date(2021, 12, 25) self._test_school_holidays( year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ) def _test_school_holidays( self, year, christmas_holiday_start, spring_holiday_start, may_holiday_start, summer_holiday_start, fall_holiday_start, christmas_holiday_end, ): holidays = {} for h in self.cal.holidays(year): holidays.setdefault(h[0], []).append(h[1]) for d in range(christmas_holiday_end.day): self.assertIn( "Christmas holiday", holidays[christmas_holiday_end - timedelta(days=d)], ) for d in range(9): self.assertIn( "Spring holiday", holidays[spring_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "May holiday", holidays[may_holiday_start + timedelta(days=d)], ) for d in range(44): self.assertIn( "Summer holiday", holidays[summer_holiday_start + timedelta(days=d)], ) for d in range(9): self.assertIn( "Fall holiday", holidays[fall_holiday_start + timedelta(days=d)], ) for d in range(31 - christmas_holiday_start.day + 1): self.assertIn( "Christmas holiday", holidays[christmas_holiday_start + timedelta(days=d)], ) class NetherlandsWithCarnivalTest(GenericCalendarTest): cal_class = Netherlands kwargs = dict(include_carnival=True) def test_year_2020(self): holidays = dict(self.cal.holidays(2020)) self.assertEqual( holidays[date(2020, 2, 23)], "Carnival" ) self.assertEqual( holidays[date(2020, 2, 24)], "Carnival" ) self.assertEqual( holidays[date(2020, 2, 25)], "Carnival" ) def test_year_2021(self): holidays = dict(self.cal.holidays(2021)) self.assertEqual( holidays[date(2021, 2, 14)], "Carnival" ) self.assertEqual( holidays[date(2021, 2, 15)], "Carnival" ) self.assertEqual( holidays[date(2021, 2, 16)], "Carnival" ) class NetherlandsWithSchoolHolidaysAndCarnivalTest(GenericCalendarTest): cal_class = NetherlandsWithSchoolHolidays kwargs = dict(region="south", carnival_instead_of_spring=True) def test_year_2020(self): holidays = dict(self.cal.holidays(2020)) for d in range(9): self.assertIn( "Carnival holiday", holidays[date(2020, 2, 22) + timedelta(days=d)], ) def test_year_2021(self): holidays = dict(self.cal.holidays(2021)) for d in range(9): self.assertIn( "Carnival holiday", holidays[date(2021, 2, 13) + timedelta(days=d)], ) class RomaniaTest(GenericCalendarTest): cal_class = Romania def test_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # Anul Nou New Year's Day self.assertIn(date(2017, 1, 2), holidays) # Anul Nou Day after New Yr self.assertIn(date(2017, 1, 24), holidays) # Unirea Principatelor Rom self.assertIn(date(2017, 4, 14), holidays) # Orthodox Good Fri self.assertIn(date(2017, 4, 16), holidays) # Orthodox Easter Sun self.assertIn(date(2017, 4, 17), holidays) # Orthodox Easter Mon self.assertIn(date(2017, 5, 1), holidays) # Ziua Muncii Labour Day self.assertIn(date(2017, 6, 1), holidays) # Ziua Copilului Children's self.assertIn(date(2017, 6, 4), holidays) # Pentecost self.assertIn(date(2017, 6, 5), holidays) # Whit Monday self.assertIn(date(2017, 8, 15), holidays) # Adormirea Maicii Domnului self.assertIn(date(2017, 11, 30), holidays) # Sfântul Andrei St. Andre self.assertIn(date(2017, 12, 1), holidays) # Ziua Națională/Marea Unir self.assertIn(date(2017, 12, 25), holidays) # Crăciunul Christmas self.assertIn(date(2017, 12, 26), holidays) # Crăciunul Christmas def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # Anul Nou New Year's Day self.assertIn(date(2019, 1, 2), holidays) # Anul Nou Day after New Yr self.assertIn(date(2019, 1, 24), holidays) # Unirea Principatelor Rom self.assertIn(date(2019, 4, 26), holidays) # Orthodox Good Fri self.assertIn(date(2019, 4, 28), holidays) # Orthodox Easter Sun self.assertIn(date(2019, 4, 29), holidays) # Orthodox Easter Mon self.assertIn(date(2019, 5, 1), holidays) # Ziua Muncii Labour Day self.assertIn(date(2019, 6, 1), holidays) # Ziua Copilului Children's self.assertIn(date(2019, 6, 16), holidays) # Pentecost self.assertIn(date(2019, 6, 17), holidays) # Whit Monday self.assertIn(date(2019, 8, 15), holidays) # Adormirea Maicii Domnului self.assertIn(date(2019, 11, 30), holidays) # Sfântul Andrei St. Andre self.assertIn(date(2019, 12, 1), holidays) # Ziua Națională/Marea Unir self.assertIn(date(2019, 12, 25), holidays) # Crăciunul Christmas self.assertIn(date(2019, 12, 26), holidays) # Crăciunul Christmas def test_liberation_day(self): # Liberation day only happened between 1949 and 1990 (incl.) liberation_day_1989 = date(1989, 8, 23) holidays = self.cal.holidays_set(1989) self.assertIn(liberation_day_1989, holidays) liberation_day_1990 = date(1990, 8, 23) holidays = self.cal.holidays_set(1990) self.assertIn(liberation_day_1990, holidays) liberation_day_1991 = date(1991, 8, 23) holidays = self.cal.holidays_set(1991) self.assertNotIn(liberation_day_1991, holidays) def test_no_orthodox_christmas(self): # This calendar is an Orthodox calendar, but there's no Jan XMas holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 1, 7), holidays) class RussiaTest(GenericCalendarTest): cal_class = Russia def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New Year's Day self.assertIn(date(2018, 1, 2), holidays) # Day after New Year self.assertIn(date(2018, 1, 7), holidays) # Christmas self.assertIn(date(2018, 2, 23), holidays) # Defendence of Fatherland self.assertIn(date(2018, 3, 8), holidays) # International Women's Day self.assertIn(date(2018, 5, 1), holidays) # Labour Day self.assertIn(date(2018, 5, 9), holidays) # Victory Day self.assertIn(date(2018, 6, 12), holidays) # National Day self.assertIn(date(2018, 11, 4), holidays) # Independence Day def test_year_2020_shift(self): holidays = dict(self.cal.holidays(2020)) # Defender of the Fatherland Day self.assertIn(date(2020, 2, 23), holidays) # SUN => Shift to MON self.assertIn(date(2020, 2, 24), holidays) self.assertEqual( holidays[date(2020, 2, 24)], "Defendence of the Fatherland shift" ) # International Women's Day self.assertIn(date(2020, 3, 8), holidays) # SUN => Shift to MON self.assertIn(date(2020, 3, 9), holidays) self.assertEqual( holidays[date(2020, 3, 9)], "International Women's Day shift" ) # Victory Day self.assertIn(date(2020, 5, 9), holidays) # SAT => Shift to MON self.assertIn(date(2020, 5, 11), holidays) self.assertEqual( holidays[date(2020, 5, 11)], "Victory Day shift" ) def test_covid19_2020(self): # By decree, several days of March and April were defined # as non-working days because of the COVID-19 crisis. # It spans from March 28th to April 30th (included). holidays = self.cal.holidays_set(2020) start = date(2020, 3, 28) end = date(2020, 4, 30) for day in daterange(start, end): self.assertIn(day, holidays) # COVID-19 days in May self.assertIn(date(2020, 5, 6), holidays) # Covid-19 May #1 self.assertIn(date(2020, 5, 7), holidays) # Covid-19 May #2 self.assertIn(date(2020, 5, 8), holidays) # Covid-19 May #3 # Not for 2019, though holidays = self.cal.holidays_set(2019) start = date(2019, 3, 28) end = date(2019, 4, 30) for day in daterange(start, end): self.assertNotIn(day, holidays) def test_covid19_2020_label(self): # no "shift" for those days, all of them were non-working days holidays = self.cal.holidays(2020) start = date(2020, 3, 28) end = date(2020, 4, 30) for day, label in holidays: if start <= day <= end: self.assertNotIn("shift", label) def test_extra_days_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 5, 4), holidays) # extra day, no other info self.assertIn(date(2020, 5, 5), holidays) # Day of spring/labor day # Constitution Vote Public Holiday self.assertIn(date(2020, 7, 1), holidays) # Not in 2019 holidays = self.cal.holidays_set(2019) self.assertNotIn(date(2019, 5, 4), holidays) self.assertNotIn(date(2019, 5, 5), holidays) self.assertNotIn(date(2019, 7, 1), holidays) def test_new_year_holidays_2004(self): # At that time, only Jan 1st/2nd were holidays. holidays = self.cal.holidays_set(2004) self.assertIn(date(2004, 1, 1), holidays) # New Year's Day self.assertIn(date(2004, 1, 2), holidays) # Day after New Year self.assertNotIn(date(2004, 1, 3), holidays) # Shift of Jan 2nd self.assertNotIn(date(2004, 1, 4), holidays) # Not until 2005 self.assertNotIn(date(2004, 1, 5), holidays) # Not until 2005 self.assertNotIn(date(2004, 1, 6), holidays) # Not until 2005 self.assertIn(date(2004, 1, 7), holidays) # XMas self.assertNotIn(date(2004, 1, 8), holidays) # Not until 2005 def test_new_year_holidays_2005(self): holidays = self.cal.holidays_set(2005) self.assertIn(date(2005, 1, 1), holidays) # New Year's Day self.assertIn(date(2005, 1, 2), holidays) # Day after New Year self.assertIn(date(2005, 1, 3), holidays) # Holiday since 2005 self.assertIn(date(2005, 1, 4), holidays) # Holiday since 2005 self.assertIn(date(2005, 1, 5), holidays) # Holiday since 2005 self.assertIn(date(2005, 1, 6), holidays) # Holiday since 2005 self.assertIn(date(2005, 1, 7), holidays) # XMas self.assertIn(date(2005, 1, 8), holidays) # Part of the holiday week def test_no_december_christmas(self): # This calendar is an Orthodox calendar & it doesn't include Dec 25th holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 12, 25), holidays) def test_holidays_2021(self): holidays = self.cal.holidays(2021) holidays_2021 = [ (date(2021, 1, 1), "New year"), (date(2021, 1, 2), "Day After New Year"), # SAT (date(2021, 1, 3), "Third Day after New Year"), # SUN (date(2021, 1, 4), "Fourth Day after New Year"), (date(2021, 1, 5), "Fifth Day after New Year"), (date(2021, 1, 6), "Sixth Day after New Year"), (date(2021, 1, 7), "Christmas"), (date(2021, 1, 8), "Eighth Day after New Year"), (date(2021, 2, 22), "Day Before Defendence of the Fatherland"), (date(2021, 2, 23), "Defendence of the Fatherland"), (date(2021, 3, 8), "International Women's Day"), (date(2021, 5, 1), "The Day of Spring and Labour"), (date(2021, 5, 3), "The Day of Spring and Labour shift"), (date(2021, 5, 9), "Victory Day"), (date(2021, 5, 10), "Victory Day shift"), (date(2021, 6, 12), "National Day"), (date(2021, 6, 14), "National Day shift"), (date(2021, 11, 4), "Day of Unity"), (date(2021, 11, 5), "Day After Day of Unity"), (date(2021, 12, 31), "New Year's Eve") ] holidays_2021 = [Holiday(*h) for h in holidays_2021] self.assertEqual(holidays, holidays_2021) def test_year_2021_extra_working_day(self): self.assertTrue(self.cal.is_working_day(date(2021, 2, 20))) self.assertTrue(self.cal.is_working_day(datetime(2021, 2, 20))) self.assertTrue(self.cal.is_working_day(date(2021, 2, 19))) self.assertTrue(self.cal.is_working_day(datetime(2020, 2, 19))) def test_labour_day_label(self): # After 1992: self.cal.get_fixed_holidays(2021) self.assertEqual( self.cal.labour_day_label, "The Day of Spring and Labour") # Before 1992: self.cal.get_fixed_holidays(1991) self.assertEqual( self.cal.labour_day_label, "International Workers' Day") class UkraineTest(GenericCalendarTest): cal_class = Ukraine def test_year_1991(self): holidays = self.cal.holidays_set(1991) self.assertIn(date(1991, 6, 16), holidays) # Independence Day self.assertNotIn(date(1991, 8, 24), holidays) def test_year_1992(self): holidays = self.cal.holidays_set(1992) self.assertNotIn(date(1992, 6, 16), holidays) self.assertIn(date(1992, 8, 24), holidays) # Independence Day def test_year_2010(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 1, 1), holidays) # New Year's Day self.assertIn(date(2010, 1, 7), holidays) # Christmas (Orthodox) self.assertIn(date(2010, 3, 8), holidays) # International Women's Day self.assertIn(date(2010, 5, 1), holidays) # Workers Solidarity Day self.assertIn(date(2010, 5, 9), holidays) # Victory Day self.assertIn(date(2010, 5, 24), holidays) # Whit Monday self.assertIn(date(2010, 6, 28), holidays) # Constitution Day self.assertIn(date(2010, 8, 24), holidays) # Independence Day def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 29), holidays) # Constitution Day (moved) self.assertIn(date(2015, 10, 14), holidays) # Defender of Ukraine def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Year's Day self.assertIn(date(2016, 1, 7), holidays) # Christmas (Orthodox) self.assertIn(date(2016, 3, 8), holidays) # International Women's Day self.assertIn(date(2016, 5, 1), holidays) # Workers Solidarity Day self.assertIn(date(2016, 5, 2), holidays) # Workers Solidarity Day self.assertIn(date(2016, 5, 2), holidays) self.assertIn(date(2016, 5, 9), holidays) # Victory Day self.assertIn(date(2016, 6, 20), holidays) self.assertIn(date(2016, 6, 28), holidays) # Constitution Day self.assertIn(date(2016, 8, 24), holidays) # Day of Unity self.assertIn(date(2016, 10, 14), holidays) # Defender of Ukraine self.assertNotIn(date(2016, 12, 25), holidays) # Christmas Day def test_year_2017(self): holidays = self.cal.holidays_set(2017) # New Year's observed assert self.cal.is_observed_holiday(date(2017, 1, 2)) self.assertIn(date(2017, 1, 9), holidays) # Christmas Orthodox (moved) self.assertIn(date(2017, 12, 25), holidays) # Christmas Day def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 5, 2), holidays) # Workers Solidarity Day def test_may_1st_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual(holidays[date(2020, 5, 1)], "Workers Solidarity Day") class UnitedKingdomTest(GenericCalendarTest): cal_class = UnitedKingdom def test_year_1973(self): holidays = self.cal.holidays_set(1973) self.assertIn(date(1973, 11, 14), holidays) # royal wedding def test_year_1977(self): holidays = self.cal.holidays_set(1977) self.assertIn(date(1977, 6, 6), holidays) # Early May Bank Holiday self.assertIn(date(1977, 6, 7), holidays) # queen's silver jubilee def test_year_1981(self): holidays = self.cal.holidays_set(1981) self.assertIn(date(1981, 7, 29), holidays) # royal wedding def test_year_1999(self): holidays = self.cal.holidays_set(1999) self.assertIn(date(1999, 12, 31), holidays) # new year's eve def test_year_2002(self): holidays = self.cal.holidays_set(2002) self.assertIn(date(2002, 1, 1), holidays) # new year day self.assertIn(date(2002, 3, 29), holidays) # good friday self.assertIn(date(2002, 3, 31), holidays) # easter sunday self.assertIn(date(2002, 4, 1), holidays) # easter monday self.assertIn(date(2002, 5, 6), holidays) # Early May Bank Holiday self.assertIn(date(2002, 6, 3), holidays) # queen's golden jubilee self.assertIn(date(2002, 6, 4), holidays) # Spring Bank Holiday self.assertIn(date(2002, 8, 26), holidays) # Late Summer Bank Holiday self.assertIn(date(2002, 12, 25), holidays) # Christmas self.assertIn(date(2002, 12, 26), holidays) # Boxing Day def test_year_2011(self): holidays = self.cal.holidays_set(2011) self.assertIn(date(2011, 4, 29), holidays) # royal wedding def test_year_2012(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 1), holidays) # new year day self.assertNotIn(date(2012, 1, 2), holidays) # new year shift self.assertIn(date(2012, 4, 6), holidays) # good friday self.assertIn(date(2012, 4, 8), holidays) # easter sunday self.assertIn(date(2012, 4, 9), holidays) # easter monday self.assertIn(date(2012, 5, 7), holidays) # Early May Bank Holiday self.assertIn(date(2012, 6, 4), holidays) # Spring Bank Holiday self.assertIn(date(2012, 6, 5), holidays) # queen's diamond jubilee self.assertIn(date(2012, 8, 27), holidays) # Late Summer Bank Holiday self.assertIn(date(2012, 12, 25), holidays) # Christmas self.assertIn(date(2012, 12, 26), holidays) # Boxing Day def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year day self.assertIn(date(2013, 3, 29), holidays) # good friday self.assertIn(date(2013, 3, 31), holidays) # easter sunday self.assertIn(date(2013, 4, 1), holidays) # easter monday self.assertIn(date(2013, 5, 6), holidays) # Early May Bank Holiday self.assertIn(date(2013, 5, 27), holidays) # Spring Bank Holiday self.assertIn(date(2013, 8, 26), holidays) # Late Summer Bank Holiday self.assertIn(date(2013, 12, 25), holidays) # Christmas self.assertIn(date(2013, 12, 26), holidays) # Boxing Day def test_shift_2012(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 1), holidays) # new year day def test_shift_2011(self): holidays = self.cal.holidays_set(2011) self.assertIn(date(2011, 12, 25), holidays) # XMas day indicated self.assertIn(date(2011, 12, 26), holidays) # Boxing day # XMas observed assert self.cal.is_observed_holiday(date(2011, 12, 26)) # Boxing observed assert self.cal.is_observed_holiday(date(2011, 12, 27)) def test_shift_2015(self): """ Christmas is on a Friday and Boxing Day on a Saturday. Only Boxing Day should be shifted. """ # XMas observed assert self.cal.is_observed_holiday(date(2015, 12, 25)) # Boxing observed assert self.cal.is_observed_holiday(date(2015, 12, 28)) def test_shift_2016(self): holidays = self.cal.holidays_set(2016) observed = self.cal.observed_holidays(2016) self.assertIn(date(2016, 12, 25), holidays) # Christmas - Sunday self.assertIn(date(2016, 12, 26), observed) # Christmas - observed self.assertIn(date(2016, 12, 27), observed) # Boxing day - observed def test_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 12), holidays) # Easter Sunday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday # This is where the year 2020 becomes special: # The Early May Bank Holiday has been moved to May 8th # to commemorate the 75th anniversary of the end of WWII self.assertNotIn(date(2020, 5, 4), holidays) self.assertIn(date(2020, 5, 25), holidays) # Spring Bank Holiday self.assertIn(date(2020, 8, 31), holidays) # Late Summer Bank Holiday self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 26), holidays) # Boxing Day # Boxing observed assert self.cal.is_observed_holiday(date(2020, 12, 28)) # May the 8th is VE day holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertIn(date(2020, 5, 8), holidays) self.assertEqual( holidays[date(2020, 5, 8)], "Early May Bank Holiday (VE day)" ) def test_2022(self): holidays = self.cal.holidays_set(2022) print(holidays) observed = self.cal.observed_holidays(2022) self.assertIn(date(2022, 1, 3), observed) # New Year self.assertIn(date(2022, 4, 15), holidays) # Good Friday self.assertIn(date(2022, 4, 18), holidays) # Easter Monday self.assertIn(date(2022, 5, 2), holidays) # Early May Bank Holiday self.assertNotIn(date(2022, 5, 30), holidays) # Spring Bank Holiday self.assertIn(date(2022, 6, 2), holidays) # Spring Bank Holiday # Platinum Jubilee Bank Holiday self.assertIn(date(2022, 6, 3), holidays) self.assertIn(date(2022, 8, 29), holidays) # Summer bank holiday self.assertIn(date(2022, 12, 26), observed) # Boxing Day self.assertIn(date(2022, 12, 27), observed) # Christmas Day # State Funeral of Queen Elizabeth II self.assertIn(date(2022, 9, 19), holidays) self.assertIn(date(2022, 12, 26), observed) # Boxing Day self.assertIn(date(2022, 12, 27), observed) # Christmas Day def test_2023(self): holidays = self.cal.holidays_set(2023) observed = self.cal.observed_holidays(2023) self.assertIn(date(2023, 1, 2), observed) # New Year self.assertIn(date(2023, 4, 7), holidays) # Good Friday self.assertIn(date(2023, 4, 10), holidays) # Easter Monday self.assertIn(date(2023, 5, 1), holidays) # Early May Bank Holiday # Coronation of His Majesty King Charles III self.assertIn(date(2023, 5, 8), holidays) self.assertIn(date(2023, 5, 29), holidays) # Spring Bank Holidays self.assertIn(date(2023, 8, 28), holidays) # Summer bank holiday self.assertIn(date(2023, 12, 25), holidays) # Christmas Day self.assertIn(date(2023, 12, 26), holidays) # Boxing Day class UnitedKingdomNorthernIrelandTest(UnitedKingdomTest): cal_class = UnitedKingdomNorthernIreland def test_regional_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 17), holidays) # St Patrick's day self.assertIn(date(2013, 3, 18), holidays) # St Patrick's sub self.assertIn(date(2013, 7, 12), holidays) # Battle of the Boyne def test_regional_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 7, 12), holidays) # Battle of the Boyne self.assertIn(date(2014, 7, 14), holidays) # Battle of the Boyne sub class GuernseyTest(GenericCalendarTest): cal_class = Guernsey def test_2020(self): holidays = self.cal.holidays_set(2020) observed = self.cal.observed_holidays(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday # This is where the year 2020 becomes special: # The Early May Bank Holiday has been moved to May 8th # to commemorate the 75th anniversary of the end of WWII self.assertNotIn(date(2020, 5, 4), holidays) self.assertIn(date(2020, 5, 25), holidays) # Spring Bank Holiday self.assertIn(date(2020, 8, 31), holidays) # Late Summer Bank Holiday self.assertIn(date(2020, 12, 25), holidays) # Christmas Day self.assertIn(date(2020, 12, 26), holidays) # 'Boxing Day self.assertIn(date(2020, 12, 28), observed) # Boxing Day Shift # May the 8th is VE day holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertIn(date(2020, 5, 8), holidays) self.assertEqual( holidays[date(2020, 5, 8)], "Early May bank holiday (VE day)" ) def test_2021(self): holidays = self.cal.holidays_set(2021) observed = self.cal.observed_holidays(2021) self.assertIn(date(2021, 1, 1), holidays) # New Year self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 3), holidays) # May Day Bank Holiday self.assertIn(date(2021, 5, 9), holidays) # Liberation Day self.assertIn(date(2021, 5, 31), holidays) # Spring Bank Holiday self.assertIn(date(2021, 8, 30), holidays) # Late Summer Bank Holiday self.assertIn(date(2021, 12, 27), observed) # Christmas Day self.assertIn(date(2021, 12, 28), observed) # Boxing Day Shift def test_2022(self): holidays = self.cal.holidays_set(2022) observed = self.cal.observed_holidays(2022) self.assertIn(date(2022, 1, 3), observed) # New Year self.assertIn(date(2022, 4, 15), holidays) # Good Friday self.assertIn(date(2022, 4, 18), holidays) # Easter Monday self.assertIn(date(2022, 5, 2), holidays) # May Day bank Holiday self.assertIn(date(2022, 5, 9), holidays) # Liberation Day self.assertIn(date(2022, 5, 30), holidays) # Spring Bank Holiday self.assertIn(date(2022, 8, 29), holidays) # Late Summer Bank Holiday self.assertIn(date(2022, 12, 26), observed) # 'Boxing Day self.assertIn(date(2022, 12, 27), observed) # Christmas Day class EuropeanCentralBankTest(GenericCalendarTest): cal_class = EuropeanCentralBank def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) # New year's day self.assertIn(date(2014, 4, 18), holidays) # Good friday self.assertIn(date(2014, 4, 21), holidays) # easter monday self.assertIn(date(2014, 5, 1), holidays) # Labour day self.assertIn(date(2014, 12, 25), holidays) # XMas self.assertIn(date(2014, 12, 26), holidays) # St Stephen class BelgiumTest(GenericCalendarTest): cal_class = Belgium def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) self.assertIn(date(2014, 4, 21), holidays) self.assertIn(date(2014, 5, 1), holidays) self.assertIn(date(2014, 5, 29), holidays) self.assertIn(date(2014, 6, 9), holidays) self.assertIn(date(2014, 7, 21), holidays) self.assertIn(date(2014, 8, 15), holidays) self.assertIn(date(2014, 11, 1), holidays) self.assertIn(date(2014, 11, 11), holidays) self.assertIn(date(2014, 12, 25), holidays) def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 4, 6), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 14), holidays) self.assertIn(date(2015, 5, 25), holidays) self.assertIn(date(2015, 7, 21), holidays) self.assertIn(date(2015, 8, 15), holidays) self.assertIn(date(2015, 11, 1), holidays) self.assertIn(date(2015, 12, 25), holidays) class PortugalTest(GenericCalendarTest): cal_class = Portugal def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # Ano Novo self.assertIn(date(2015, 4, 3), holidays) # Sexta-Feira Santa self.assertIn(date(2015, 4, 5), holidays) # Domingo de Páscoa self.assertIn(date(2015, 4, 25), holidays) # Dia da Liberdade self.assertIn(date(2015, 5, 1), holidays) # Dia do Trabalhador self.assertIn(date(2015, 6, 10), holidays) # Dia de Portugal self.assertIn(date(2015, 8, 15), holidays) # Assunção de Nossa Senhora self.assertIn(date(2015, 12, 8), holidays) # Imaculada Conceição self.assertIn(date(2015, 12, 25), holidays) # Natal self.assertNotIn(date(2015, 6, 4), holidays) # Corpus Christi self.assertNotIn(date(2015, 10, 5), holidays) # Todos os santos self.assertNotIn(date(2015, 11, 1), holidays) # todos os santos # Restauração da Independência self.assertNotIn(date(2015, 12, 1), holidays) def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # Ano Novo self.assertIn(date(2016, 3, 25), holidays) # Sexta-Feira Santa self.assertIn(date(2016, 3, 27), holidays) # Domingo de Páscoa self.assertIn(date(2016, 4, 25), holidays) # Dia da Liberdade self.assertIn(date(2016, 5, 1), holidays) # Dia do Trabalhador self.assertIn(date(2016, 6, 10), holidays) # Dia de Portugal self.assertIn(date(2016, 8, 15), holidays) # Assunção de Nossa Senhora self.assertIn(date(2016, 12, 8), holidays) # Imaculada Conceição self.assertIn(date(2016, 12, 25), holidays) # Natal self.assertIn(date(2016, 5, 26), holidays) # Corpus Christi self.assertIn(date(2016, 10, 5), holidays) # Implantação da República self.assertIn(date(2016, 11, 1), holidays) # Todos os santos # Restauração da Independência self.assertIn(date(2016, 12, 1), holidays) def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Dia do Trabalhador") def test_immaculate_conception_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual(holidays[date(2020, 12, 8)], "Imaculada Conceição") class SerbiaTest(GenericCalendarTest): cal_class = Serbia def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 1, 2), holidays) self.assertIn(date(2015, 1, 7), holidays) self.assertIn(date(2015, 2, 15), holidays) self.assertIn(date(2015, 2, 16), holidays) self.assertIn(date(2015, 4, 10), holidays) self.assertIn(date(2015, 4, 12), holidays) self.assertIn(date(2015, 4, 13), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 2), holidays) self.assertIn(date(2015, 11, 11), holidays) def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) self.assertIn(date(2016, 1, 2), holidays) self.assertIn(date(2016, 1, 7), holidays) self.assertIn(date(2016, 2, 15), holidays) self.assertIn(date(2016, 2, 16), holidays) self.assertIn(date(2016, 4, 29), holidays) self.assertIn(date(2016, 5, 1), holidays) self.assertIn(date(2016, 5, 2), holidays) self.assertIn(date(2016, 11, 11), holidays) def test_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) self.assertIn(date(2017, 1, 2), holidays) self.assertIn(date(2017, 1, 7), holidays) self.assertIn(date(2017, 2, 15), holidays) self.assertIn(date(2017, 2, 16), holidays) self.assertIn(date(2017, 4, 14), holidays) self.assertIn(date(2017, 4, 16), holidays) self.assertIn(date(2017, 4, 17), holidays) self.assertIn(date(2017, 5, 1), holidays) self.assertIn(date(2017, 5, 2), holidays) self.assertIn(date(2017, 11, 11), holidays) def test_no_december_christmas(self): # This calendar is an Orthodox calendar & it doesn't include Dec 25th holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 12, 25), holidays) class SloveniaTest(GenericCalendarTest): cal_class = Slovenia def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 2, 8), holidays) self.assertIn(date(2015, 4, 5), holidays) self.assertIn(date(2015, 4, 6), holidays) self.assertIn(date(2015, 4, 27), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 2), holidays) self.assertIn(date(2015, 5, 24), holidays) self.assertIn(date(2015, 6, 25), holidays) self.assertIn(date(2015, 8, 15), holidays) self.assertIn(date(2015, 10, 31), holidays) self.assertIn(date(2015, 11, 1), holidays) self.assertIn(date(2015, 12, 25), holidays) self.assertIn(date(2015, 12, 26), holidays) def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) self.assertIn(date(2016, 2, 8), holidays) self.assertIn(date(2016, 3, 27), holidays) self.assertIn(date(2016, 3, 28), holidays) self.assertIn(date(2016, 4, 27), holidays) self.assertIn(date(2016, 5, 1), holidays) self.assertIn(date(2016, 5, 2), holidays) self.assertIn(date(2016, 5, 15), holidays) self.assertIn(date(2016, 6, 25), holidays) self.assertIn(date(2016, 8, 15), holidays) self.assertIn(date(2016, 10, 31), holidays) self.assertIn(date(2016, 11, 1), holidays) self.assertIn(date(2016, 12, 25), holidays) self.assertIn(date(2016, 12, 26), holidays) def test_january_second(self): # From 1955 until May 2012, when the National Assembly of Slovenia # passed the Public Finance Balance Act, 2 January was a work-free day. # It has been re-introduced in 2017. # Source - Wikipedia # https://en.wikipedia.org/wiki/Public_holidays_in_Slovenia # Before 1955... holidays = self.cal.holidays_set(1953) self.assertNotIn(date(1953, 1, 2), holidays) holidays = self.cal.holidays_set(1954) self.assertNotIn(date(1953, 1, 2), holidays) # Ranging from 1955 to 2012 for year in range(1955, 2013): holidays = self.cal.holidays_set(year) self.assertIn(date(year, 1, 2), holidays) # As of 2012, it was no more for year in range(2013, 2017): holidays = self.cal.holidays_set(year) self.assertNotIn(date(year, 1, 2), holidays) # In 2017, january 2nd became a state holiday holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 2), holidays) class EstoniaTest(GenericCalendarTest): cal_class = Estonia def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # new year self.assertIn(date(2015, 2, 24), holidays) # independence day self.assertIn(date(2015, 4, 3), holidays) # good friday self.assertIn(date(2015, 4, 5), holidays) # easter sunday self.assertIn(date(2015, 5, 1), holidays) # spring day self.assertIn(date(2015, 5, 24), holidays) # pentecost self.assertIn(date(2015, 6, 23), holidays) # victory day self.assertIn(date(2015, 6, 24), holidays) # midsummer day self.assertIn(date(2015, 8, 20), holidays) # restoration of independ. self.assertIn(date(2015, 12, 24), holidays) # XMas eve self.assertIn(date(2015, 12, 25), holidays) # XMas self.assertIn(date(2015, 12, 26), holidays) # Boxing day def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # new year self.assertIn(date(2016, 2, 24), holidays) # independence day self.assertIn(date(2016, 3, 25), holidays) # good friday self.assertIn(date(2016, 3, 27), holidays) # easter sunday self.assertIn(date(2016, 5, 1), holidays) # spring day self.assertIn(date(2016, 5, 15), holidays) # pentecost self.assertIn(date(2016, 6, 23), holidays) # victory day self.assertIn(date(2016, 6, 24), holidays) # midsummer day self.assertIn(date(2016, 8, 20), holidays) # restoration of independ. self.assertIn(date(2016, 12, 24), holidays) # XMas eve self.assertIn(date(2016, 12, 25), holidays) # XMas self.assertIn(date(2016, 12, 26), holidays) # Boxing day class LithuaniaTest(GenericCalendarTest): cal_class = Lithuania def test_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # new year self.assertIn(date(2016, 2, 16), holidays) # restoration of the state self.assertIn(date(2016, 3, 11), holidays) # restoration of independ. self.assertIn(date(2016, 3, 27), holidays) # easter sunday self.assertIn(date(2016, 3, 28), holidays) # easter monday self.assertIn(date(2016, 5, 1), holidays) # labour day / mother's day self.assertIn(date(2016, 6, 5), holidays) # father's day self.assertIn(date(2016, 6, 24), holidays) # st john's day self.assertIn(date(2016, 7, 6), holidays) # Anniversary of King Mind. self.assertIn(date(2016, 8, 15), holidays) # Assumption day self.assertIn(date(2016, 11, 1), holidays) # All saints day self.assertIn(date(2016, 12, 24), holidays) # Xmas eve self.assertIn(date(2016, 12, 25), holidays) # Xmas day self.assertIn(date(2016, 12, 26), holidays) # 2nd day of xmas def test_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 1), holidays) # new year self.assertIn(date(2017, 2, 16), holidays) # restoration of the state self.assertIn(date(2017, 3, 11), holidays) # restoration of independ. self.assertIn(date(2017, 4, 16), holidays) # easter sunday self.assertIn(date(2017, 4, 17), holidays) # easter monday self.assertIn(date(2017, 5, 1), holidays) # labour day self.assertIn(date(2017, 5, 7), holidays) # mother's day self.assertIn(date(2017, 6, 4), holidays) # father's day self.assertIn(date(2017, 6, 24), holidays) # st john's day self.assertIn(date(2017, 7, 6), holidays) # Anniversary of King Mind. self.assertIn(date(2017, 8, 15), holidays) # Assumption day self.assertIn(date(2017, 11, 1), holidays) # All saints day self.assertIn(date(2017, 12, 24), holidays) # Xmas eve self.assertIn(date(2017, 12, 25), holidays) # Xmas day self.assertIn(date(2017, 12, 26), holidays) # 2nd day of xmas def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # new year self.assertIn(date(2020, 2, 16), holidays) # restoration of the state self.assertIn(date(2020, 3, 11), holidays) # restoration of independ. self.assertIn(date(2020, 4, 12), holidays) # easter sunday self.assertIn(date(2020, 4, 13), holidays) # easter monday self.assertIn(date(2020, 5, 1), holidays) # labour day self.assertIn(date(2020, 5, 3), holidays) # mother's day self.assertIn(date(2020, 6, 7), holidays) # father's day self.assertIn(date(2020, 6, 24), holidays) # st john's day self.assertIn(date(2020, 7, 6), holidays) # Anniversary of King Mind. self.assertIn(date(2020, 8, 15), holidays) # Assumption day self.assertIn(date(2020, 11, 1), holidays) # All saints day self.assertIn(date(2020, 11, 2), holidays) # All souls day self.assertIn(date(2020, 12, 24), holidays) # Xmas eve self.assertIn(date(2020, 12, 25), holidays) # Xmas day self.assertIn(date(2020, 12, 26), holidays) # 2nd day of xmas def test_all_souls_day(self): # All Souls day was introduced as of 2020 # https://en.wikipedia.org/wiki/Public_holidays_in_Lithuania holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 11, 2), holidays) holidays = self.cal.holidays_set(2019) self.assertNotIn(date(2019, 11, 2), holidays) holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 11, 2), holidays) calendra-7.9.0/calendra/tests/test_germany.py000066400000000000000000000254541457013633400213060ustar00rootroot00000000000000from datetime import date from unittest import TestCase from . import GenericCalendarTest from ..europe import ( Germany, BadenWurttemberg, Bavaria, Berlin, Brandenburg, Bremen, Hamburg, Hesse, MecklenburgVorpommern, LowerSaxony, NorthRhineWestphalia, RhinelandPalatinate, Saarland, Saxony, SaxonyAnhalt, SchleswigHolstein, Thuringia ) class ReformationFlagTest(TestCase): def test_flags_reformation_day(self): klasses = ( BadenWurttemberg, Bavaria, Berlin, Brandenburg, Bremen, Hamburg, Hesse, MecklenburgVorpommern, LowerSaxony, NorthRhineWestphalia, RhinelandPalatinate, Saarland, Saxony, SaxonyAnhalt, SchleswigHolstein, Thuringia ) for klass in klasses: if klass in (Bremen, Hamburg, LowerSaxony, SchleswigHolstein): self.assertTrue(klass.include_reformation_day_2018) else: self.assertFalse(klass.include_reformation_day_2018) class GermanyTest(GenericCalendarTest): cal_class = Germany def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) self.assertIn(date(2014, 4, 18), holidays) self.assertIn(date(2014, 4, 21), holidays) self.assertIn(date(2014, 5, 1), holidays) self.assertIn(date(2014, 5, 29), holidays) self.assertIn(date(2014, 6, 9), holidays) self.assertIn(date(2014, 10, 3), holidays) self.assertIn(date(2014, 12, 25), holidays) self.assertIn(date(2014, 12, 26), holidays) def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 4, 3), holidays) self.assertIn(date(2015, 4, 6), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 14), holidays) self.assertIn(date(2015, 5, 25), holidays) self.assertIn(date(2015, 10, 3), holidays) self.assertIn(date(2015, 12, 25), holidays) self.assertIn(date(2015, 12, 26), holidays) def test_year_reformation_day(self): # Reformation Day is included each year in: # Brandenburg, MecklenburgVorpommern, Saxony, SaxonyAnhalt & Thuringia holidays = self.cal.holidays_set(2015) if self.cal.include_reformation_day(2015): self.assertIn(date(2015, 10, 31), holidays) else: self.assertNotIn(date(2015, 10, 31), holidays) # But in the year 2017, it's included for the whole country holidays = self.cal.holidays_set(2017) self.assertTrue(self.cal.include_reformation_day(2017)) self.assertIn(date(2017, 10, 31), holidays) # In 2018, Four more states have added it: # Bremen, Hamburg, Lower Saxony and Schleswig-Holstein holidays = self.cal.holidays_set(2018) if self.cal.include_reformation_day(2018): self.assertIn(date(2018, 10, 31), holidays) else: self.assertNotIn(date(2018, 10, 31), holidays) class BadenWurttembergTest(GermanyTest): cal_class = BadenWurttemberg def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 6), holidays) self.assertIn(date(2014, 6, 19), holidays) self.assertIn(date(2014, 11, 1), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 6), holidays) self.assertIn(date(2015, 6, 4), holidays) self.assertIn(date(2015, 11, 1), holidays) class BavariaTest(GenericCalendarTest): cal_class = Bavaria def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) self.assertIn(date(2014, 1, 6), holidays) self.assertIn(date(2014, 4, 18), holidays) self.assertIn(date(2014, 4, 21), holidays) self.assertIn(date(2014, 5, 1), holidays) self.assertIn(date(2014, 5, 29), holidays) self.assertIn(date(2014, 6, 9), holidays) self.assertIn(date(2014, 6, 19), holidays) self.assertIn(date(2014, 8, 15), holidays) self.assertIn(date(2014, 10, 3), holidays) self.assertIn(date(2014, 11, 1), holidays) self.assertIn(date(2014, 12, 25), holidays) self.assertIn(date(2014, 12, 26), holidays) def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 1, 6), holidays) self.assertIn(date(2015, 4, 3), holidays) self.assertIn(date(2015, 4, 6), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 14), holidays) self.assertIn(date(2015, 5, 25), holidays) self.assertIn(date(2015, 6, 4), holidays) self.assertIn(date(2015, 8, 15), holidays) self.assertIn(date(2015, 10, 3), holidays) self.assertIn(date(2015, 11, 1), holidays) self.assertIn(date(2015, 12, 25), holidays) self.assertIn(date(2015, 12, 26), holidays) class BerlinTest(GermanyTest): cal_class = Berlin def test_extra_2018(self): holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 3, 8), holidays) self.assertNotIn(date(2018, 5, 8), holidays) def test_extra_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 8), holidays) self.assertNotIn(date(2019, 5, 8), holidays) def test_extra_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 3, 8), holidays) self.assertIn(date(2020, 5, 8), holidays) def test_extra_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 3, 8), holidays) self.assertNotIn(date(2021, 5, 8), holidays) class BrandenburgTest(GenericCalendarTest): cal_class = Brandenburg def test_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) self.assertIn(date(2014, 4, 18), holidays) self.assertIn(date(2014, 4, 20), holidays) self.assertIn(date(2014, 4, 21), holidays) self.assertIn(date(2014, 5, 1), holidays) self.assertIn(date(2014, 5, 29), holidays) self.assertIn(date(2014, 6, 9), holidays) self.assertIn(date(2014, 10, 3), holidays) self.assertIn(date(2014, 10, 31), holidays) self.assertIn(date(2014, 12, 25), holidays) self.assertIn(date(2014, 12, 26), holidays) def test_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) self.assertIn(date(2015, 4, 3), holidays) self.assertIn(date(2015, 4, 5), holidays) self.assertIn(date(2015, 4, 6), holidays) self.assertIn(date(2015, 5, 1), holidays) self.assertIn(date(2015, 5, 14), holidays) self.assertIn(date(2015, 5, 25), holidays) self.assertIn(date(2015, 10, 3), holidays) self.assertIn(date(2015, 10, 31), holidays) self.assertIn(date(2015, 12, 25), holidays) self.assertIn(date(2015, 12, 26), holidays) class BremenTest(GermanyTest): cal_class = Bremen class HamburgTest(GermanyTest): cal_class = Hamburg class HesseTest(GermanyTest): cal_class = Hesse def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 19), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 4), holidays) class MecklenburgVorpommernTest(GermanyTest): cal_class = MecklenburgVorpommern def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 10, 31), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 10, 31), holidays) class LowerSaxonyTest(GermanyTest): cal_class = LowerSaxony class NorthRhineWestphaliaTest(GermanyTest): cal_class = NorthRhineWestphalia def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 19), holidays) self.assertIn(date(2014, 11, 1), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 4), holidays) self.assertIn(date(2015, 11, 1), holidays) class RhinelandPalatinateTest(GermanyTest): cal_class = RhinelandPalatinate def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 19), holidays) self.assertIn(date(2014, 11, 1), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 4), holidays) self.assertIn(date(2015, 11, 1), holidays) class SaarlandTest(GermanyTest): cal_class = Saarland def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 19), holidays) self.assertIn(date(2014, 8, 15), holidays) self.assertIn(date(2014, 11, 1), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 4), holidays) self.assertIn(date(2015, 8, 15), holidays) self.assertIn(date(2015, 11, 1), holidays) class SaxonyTest(GermanyTest): cal_class = Saxony def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 19), holidays) self.assertIn(date(2014, 10, 31), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 18), holidays) self.assertIn(date(2015, 10, 31), holidays) def test_extra_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 11, 16), holidays) self.assertNotIn(date(2016, 11, 23), holidays) self.assertIn(date(2016, 10, 31), holidays) class SaxonyAnhaltTest(GermanyTest): cal_class = SaxonyAnhalt def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 10, 31), holidays) self.assertIn(date(2014, 1, 6), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 10, 31), holidays) self.assertIn(date(2015, 1, 6), holidays) class SchleswigHolsteinTest(GermanyTest): cal_class = SchleswigHolstein class ThuringiaTest(GermanyTest): cal_class = Thuringia def test_extra_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 10, 31), holidays) def test_extra_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 10, 31), holidays) calendra-7.9.0/calendra/tests/test_global_registry.py000066400000000000000000000007671457013633400230340ustar00rootroot00000000000000from unittest import TestCase from ..registry import registry class GlobalRegistry(TestCase): def test_name(self): for klass in registry.region_registry.values(): # All classes have a `name` class property self.assertTrue(hasattr(klass, 'name')) # All classes have a non-empty name self.assertTrue(klass.name) # All those properties are equivalent to the class docstring self.assertEqual(klass.name, klass.__doc__) calendra-7.9.0/calendra/tests/test_ical_export.py000066400000000000000000000121021457013633400221370ustar00rootroot00000000000000import tempfile from pathlib import Path from ..core import Calendar from ..exceptions import ICalExportRangeError, ICalExportTargetPathError from . import CoreCalendarTest class FakeCalendar(Calendar): """Fake Calendar""" class IcalExportPeriodTest(CoreCalendarTest): cal_class = FakeCalendar def test_empty_range(self): # No period means 2000-2030 result = self.cal._get_ical_period() self.assertEqual(len(result), 2) self.assertEqual(result[0], 2000) self.assertEqual(result[1], 2030) # No period means 2000-2030 result = self.cal._get_ical_period(period=()) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2000) self.assertEqual(result[1], 2030) # No period means 2000-2030 result = self.cal._get_ical_period(period=[]) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2000) self.assertEqual(result[1], 2030) def test_range_lists(self): # Period: 2010-2020 result = self.cal._get_ical_period(period=[2010, 2020]) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Bad period: 2020-2010 => Swap terms result = self.cal._get_ical_period(period=[2020, 2010]) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Too long of a list => take the extremes result = self.cal._get_ical_period(period=[2010, 2015, 2020]) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Assume that the range is only one year result = self.cal._get_ical_period(period=[2020, 2020]) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2020) self.assertEqual(result[1], 2020) def test_range_tuples(self): # Period: 2010-2020 result = self.cal._get_ical_period(period=(2010, 2020)) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Bad period: 2020-2010 => Swap terms result = self.cal._get_ical_period(period=(2020, 2010)) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Too long of a list => take the extremes result = self.cal._get_ical_period(period=(2010, 2015, 2020)) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2010) self.assertEqual(result[1], 2020) # Assume that the range is only one year result = self.cal._get_ical_period(period=(2020, 2020)) self.assertEqual(len(result), 2) self.assertEqual(result[0], 2020) self.assertEqual(result[1], 2020) def test_bad_ranges(self): # Bad period: String with self.assertRaises(ICalExportRangeError): self.cal._get_ical_period(period="something") # Bad period: Dict with self.assertRaises(ICalExportRangeError): self.cal._get_ical_period(period={"a": 2000, "b": "foobar"}) # Bad period: List of non-integers with self.assertRaises(ICalExportRangeError): self.cal._get_ical_period(period=["foo", "bar"]) # Bad period: Tuple of non-integers with self.assertRaises(ICalExportRangeError): self.cal._get_ical_period(period=("foo", "bar")) class ICalExportTargetPath(CoreCalendarTest): cal_class = FakeCalendar def test_empty_path(self): with self.assertRaises(ICalExportTargetPathError): self.cal._get_ical_target_path("") with self.assertRaises(ICalExportTargetPathError): self.cal._get_ical_target_path(None) def test_target_is_directory(self): temp_dir = Path(tempfile.gettempdir()) / "failed_ical_tests" temp_dir.mkdir(parents=True, exist_ok=True) with self.assertRaises(ICalExportTargetPathError): self.cal._get_ical_target_path(temp_dir) def test_no_extension(self): # Relative paths self.assertEqual(self.cal._get_ical_target_path("a"), Path("a.ics")) self.assertEqual( self.cal._get_ical_target_path("a/b"), Path("a/b.ics") ) # Absolute path self.assertEqual( self.cal._get_ical_target_path("/path/to/a"), Path("/path/to/a.ics") ) def test_known_extensions(self): for ext in ('ical', 'ics', 'ifb', 'icalendar'): filename = Path(f"a.{ext}") self.assertEqual( self.cal._get_ical_target_path(filename), filename ) def test_added_extensions(self): self.assertEqual(self.cal._get_ical_target_path('a.'), Path('a..ics')) self.assertEqual( self.cal._get_ical_target_path('a.txt'), Path('a.txt.ics') ) self.assertEqual( self.cal._get_ical_target_path('.test'), Path('.test.ics') ) calendra-7.9.0/calendra/tests/test_mozambique.py000066400000000000000000000127111457013633400220050ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..africa.mozambique import Mozambique class MozambiqueTest(GenericCalendarTest): cal_class = Mozambique def test_year_new_year_shift(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) self.assertNotIn(date(2019, 1, 2), holidays) holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) self.assertNotIn(date(2020, 1, 2), holidays) def test_n_holidays(self): n_holidays = len(self.cal.holidays_set(2019)) for holiday in self.cal.get_calendar_holidays(2020): print(holiday) assert n_holidays == 10 def test_year_2018(self): holidays = self.cal.holidays_set(2018) # Fixed days section: # 1. New Year's Day self.assertIn(date(2018, 1, 1), holidays) # 2. Mozambican Heroes' Day self.assertIn(date(2018, 2, 3), holidays) # 3. Mozambican Women's Day self.assertIn(date(2018, 4, 7), holidays) # 4. Good Friday self.assertIn(date(2018, 3, 30), holidays) # 5. Labour Day self.assertIn(date(2018, 5, 1), holidays) # 6. Independence Day self.assertIn(date(2018, 6, 25), holidays) # 7. Victory Day self.assertIn(date(2018, 9, 7), holidays) # 8. Armed Forces Day self.assertIn(date(2018, 9, 25), holidays) # 9. Peace And Reconciliation Day self.assertIn(date(2018, 10, 4), holidays) # 10. Christmas day self.assertIn(date(2018, 12, 25), holidays) def test_year_2019(self): holidays = self.cal.holidays_set(2019) # Fixed days section: # 1. New Year's Day self.assertIn(date(2019, 1, 1), holidays) # 2. Mozambican Heroes' Day self.assertIn(date(2019, 2, 3), holidays) # 3. Mozambican Women's Day self.assertIn(date(2019, 4, 7), holidays) # 4. Good Friday self.assertIn(date(2019, 4, 19), holidays) # 5. Labour Day self.assertIn(date(2019, 5, 1), holidays) # 6. Independence Day self.assertIn(date(2019, 6, 25), holidays) # 7. Victory Day self.assertIn(date(2019, 9, 7), holidays) # 8. Armed Forces Day self.assertIn(date(2019, 9, 25), holidays) # 9. Peace And Reconciliation Day self.assertIn(date(2019, 10, 4), holidays) # 10. Christmas day self.assertIn(date(2019, 12, 25), holidays) def test_year_2020(self): holidays = self.cal.holidays_set(2020) # Fixed days section: # 1. New Year's Day self.assertIn(date(2020, 1, 1), holidays) # 2. Mozambican Heroes' Day self.assertIn(date(2020, 2, 3), holidays) # 3. Mozambican Women's Day self.assertIn(date(2020, 4, 7), holidays) # 4. Good Friday self.assertIn(date(2020, 4, 10), holidays) # 5. Labour Day self.assertIn(date(2020, 5, 1), holidays) # 6. Independence Day self.assertIn(date(2020, 6, 25), holidays) # 7. Victory Day self.assertIn(date(2020, 9, 7), holidays) # 8. Armed Forces Day self.assertIn(date(2020, 9, 25), holidays) # 9. Peace And Reconciliation Day self.assertIn(date(2020, 10, 4), holidays) # 10. Christmas day self.assertIn(date(2020, 12, 25), holidays) def test_2020_new_years_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 1, 1)], "New year") def test_2020_heroes_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 2, 3)], "Mozambican Heroes' Day") def test_2020_women_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 4, 7)], "Mozambican Women's Day") def test_2020_good_friday_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 4, 10)], "Good Friday") def test_2020_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Labour Day") def test_2020_independence_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 6, 25)], "Independence Day") def test_2020_victory_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 9, 7)], "Victory Day") def test_2020_armed_forces_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 9, 25)], "Armed Forces Day") def test_2020_peace_and_reconciliation_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 10, 4)], "Peace And Reconciliation Day") def test_2020_christmas_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 12, 25)], "Christmas Day") calendra-7.9.0/calendra/tests/test_oceania.py000066400000000000000000000325511457013633400212370ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..oceania import ( Australia, AustralianCapitalTerritory, NewSouthWales, NorthernTerritory, Queensland, SouthAustralia, Tasmania, Hobart, Victoria, WesternAustralia, MarshallIslands, NewZealand ) class AustraliaTest(GenericCalendarTest): cal_class = Australia def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 26), holidays) self.assertIn(date(2013, 1, 28), holidays) # Australia day shift self.assertIn(date(2013, 1, 26), holidays) self.assertIn(date(2013, 3, 29), holidays) # Good Friday self.assertIn(date(2013, 4, 25), holidays) self.assertIn(date(2013, 12, 25), holidays) def test_new_year_shift(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 2), holidays) # 1st was a sunday def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 4, 26), holidays) def test_oceania_shift_2016(self): holidays = self.cal.holidays_set(2016) # Christmas day is on sunday in 2016 # Boxing day is on 26th self.assertIn(date(2016, 12, 26), holidays) # Boxing day shift on 27th self.assertIn(date(2016, 12, 27), holidays) def test_oceania_shift_2009(self): holidays = self.cal.holidays_set(2009) # Boxing day is on saturday in 2009 # Boxing day is on 26th self.assertIn(date(2009, 12, 26), holidays) # Boxing day shift on 28th self.assertIn(date(2009, 12, 28), holidays) class AustraliaCapitalTerritoryTest(AustraliaTest): cal_class = AustralianCapitalTerritory def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 11), holidays) self.assertIn(date(2013, 3, 30), holidays) # Easter Saturday self.assertIn(date(2013, 4, 1), holidays) # Easter Monday self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 9, 30), holidays) # Family & Community day self.assertIn(date(2013, 10, 7), holidays) # Labour day october self.assertIn(date(2013, 12, 26), holidays) # Boxing day def test_family_community_day_before_2007(self): # There were no Family and Community day before 2007 for year in range(1970, 2007): self.assertIsNone(self.cal.get_family_community_day(year)) holidays = self.cal.holidays(year) holidays = dict(holidays) labels = holidays.values() self.assertNotIn(self.cal._family_community_label, labels) def test_family_community_day_2007_2017_presence(self): # Family & Community day was included [2007 -> 2017] for year in range(2007, 2018): self.assertIsNotNone(self.cal.get_family_community_day(year)) holidays = self.cal.holidays(year) holidays = dict(holidays) labels = holidays.values() self.assertIn(self.cal._family_community_label, labels) def test_family_community_day_after_2017(self): # Starting of 2018 this day would no longer exist for year in range(2018, date.today().year + 1): self.assertIsNone(self.cal.get_family_community_day(year)) holidays = self.cal.holidays(year) holidays = dict(holidays) labels = holidays.values() print(labels) self.assertNotIn(self.cal._family_community_label, labels) def test_reconciliation_day(self): reconciliation_day = self.cal.get_reconciliation_day(2017) self.assertIsNone(reconciliation_day) reconciliation_day = self.cal.get_reconciliation_day(2018) self.assertEqual(reconciliation_day, (date(2018, 5, 28), "Reconciliation Day Shift")) reconciliation_day = self.cal.get_reconciliation_day(2019) self.assertEqual(reconciliation_day, (date(2019, 5, 27), "Reconciliation Day")) class NewSouthWalesTest(AustraliaTest): cal_class = NewSouthWales def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 30), holidays) # Good friday self.assertIn(date(2013, 3, 31), holidays) # Easter Sunday self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 10, 7), holidays) # Labour day october self.assertIn(date(2013, 12, 26), holidays) # Boxing day def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 4, 26), holidays) # We don't shift if ANZAC day falls on a Saturday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 25), holidays) class NorthernTerritoryTest(AustraliaTest): cal_class = NorthernTerritory def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 30), holidays) # Easter Saturday self.assertIn(date(2013, 5, 6), holidays) # May Day self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 8, 5), holidays) # Picnic day self.assertIn(date(2013, 12, 26), holidays) # Boxing day def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 4, 26), holidays) # We don't shift if ANZAC day falls on a Saturday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 25), holidays) class QueenslandTest(AustraliaTest): cal_class = Queensland def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 30), holidays) # Easter Saturday self.assertIn(date(2013, 5, 6), holidays) # May's labour day self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 12, 26), holidays) # Boxing day def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 4, 26), holidays) # We don't shift if ANZAC day falls on a Saturday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 25), holidays) class SouthAustraliaTest(AustraliaTest): cal_class = SouthAustralia def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 11), holidays) # Adelaide's cup self.assertIn(date(2013, 3, 30), holidays) # Easter Saturday self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 10, 7), holidays) # Labour day october self.assertIn(date(2013, 12, 26), holidays) # Proclamation day def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) self.assertIn(date(2010, 4, 26), holidays) # We don't shift if ANZAC day falls on a Saturday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 25), holidays) class TasmaniaTest(AustraliaTest): cal_class = Tasmania def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 11), holidays) # Eight hours day self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 12, 26), holidays) # Boxing day self.assertIn(date(2013, 4, 25), holidays) # ANZAC day def test_anzac_shift(self): # We don't shift holidays = self.cal.holidays_set(2010) self.assertNotIn(date(2010, 4, 26), holidays) class NonHobartTest(TasmaniaTest): def test_tasmania_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 11, 4), holidays) # Recreation Day class HobartTest(TasmaniaTest): cal_class = Hobart def test_hobart_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 2, 11), holidays) # Royal Hobart Regatta # Recreation day not in Hobart self.assertNotIn(date(2013, 11, 4), holidays) # Recreation Day class VictoriaTest(AustraliaTest): cal_class = Victoria def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 11), holidays) # Labours day in march self.assertIn(date(2013, 3, 30), holidays) # Easter Saturday self.assertIn(date(2013, 6, 10), holidays) # Queen's Bday self.assertIn(date(2013, 11, 5), holidays) # Melbourne's cup self.assertIn(date(2013, 12, 26), holidays) # Boxing day self.assertIn(date(2013, 4, 25), holidays) # ANZAC day def test_anzac_shift(self): # We don't shift holidays = self.cal.holidays_set(2010) self.assertNotIn(date(2010, 4, 26), holidays) class WesternAustraliaTest(AustraliaTest): cal_class = WesternAustralia def test_regional_specific_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 3, 4), holidays) # Labours day in march self.assertIn(date(2013, 6, 3), holidays) # Western Australia Day self.assertIn(date(2013, 12, 26), holidays) # Boxing day # It is not possible to surely compute Queen's Birthday holiday in # The western Australia territory, since it's based on the Governor # Decision (it is typically the last Monday of September or the first # Monday of October) class MarshallIslandsTest(GenericCalendarTest): cal_class = MarshallIslands def test_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # new year self.assertIn(date(2013, 3, 3), holidays) # Remembrance day self.assertIn(date(2013, 3, 29), holidays) # (good friday) self.assertIn(date(2013, 5, 1), holidays) # constitution day self.assertIn(date(2013, 7, 5), holidays) # Fishermens self.assertIn(date(2013, 9, 6), holidays) # labour day self.assertIn(date(2013, 9, 27), holidays) # Manit Day self.assertIn(date(2013, 11, 17), holidays) # presidents day self.assertIn(date(2013, 12, 6), holidays) # gospel day self.assertIn(date(2013, 12, 25), holidays) # Xmas self.assertIn(date(2013, 12, 31), holidays) # new year's eve class NewZealandTest(GenericCalendarTest): cal_class = NewZealand def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New Year's Day self.assertIn(date(2018, 1, 2), holidays) # Day after New Year's Day self.assertIn(date(2018, 2, 6), holidays) # Waitangi Day self.assertIn(date(2018, 3, 30), holidays) # Good Friday self.assertIn(date(2018, 4, 2), holidays) # Easter Monday self.assertIn(date(2018, 4, 25), holidays) # ANZAC Day self.assertIn(date(2018, 6, 4), holidays) # Queen's Birthday self.assertIn(date(2018, 10, 22), holidays) # Labour Day self.assertIn(date(2018, 12, 25), holidays) # Christmas Day self.assertIn(date(2018, 12, 26), holidays) # Boxing Day def test_new_year_shift_on_sunday(self): holidays = self.cal.holidays_set(2012) # New Years was on a SUN # Day After New Years is on the 2nd self.assertIn(date(2012, 1, 2), holidays) # New Years observed on the 3rd assert self.cal.is_observed_holiday(date(2012, 1, 3)) # No shift of a shift self.assertNotIn(date(2012, 1, 4), holidays) def test_new_year_shift_on_saturday(self): holidays = self.cal.holidays_set(2022) # New Years is on a SAT # The day after is still a holiday self.assertIn(date(2022, 1, 2), holidays) # The shift is on the MON, 3rd observed = self.cal.observed_holidays(2022) self.assertIn(date(2022, 1, 3), observed) # And there's a shift of the shift self.assertIn(date(2022, 1, 4), observed) def test_anzac_shift(self): holidays = self.cal.holidays_set(2010) # 25th was a sunday # ANZAC Day is on 25th self.assertIn(date(2010, 4, 25), holidays) # ANZAC Day observed on 26th assert self.cal.is_observed_holiday(date(2010, 4, 26)) def test_waitangi_shift(self): holidays = self.cal.holidays_set(2016) # 6th was a saturday # Waitangi Day is on 6th self.assertIn(date(2016, 2, 6), holidays) # Waitangi Day observed on 8th assert self.cal.is_observed_holiday(date(2016, 2, 8)) def test_oceania_shift_2016(self): holidays = self.cal.holidays_set(2016) # Christmas day is on sunday in 2016 # Boxing day is on 26th self.assertIn(date(2016, 12, 26), holidays) # Christmas day observed on 26th and boxing day on 27th assert self.cal.is_observed_holiday(date(2016, 12, 26)) assert self.cal.is_observed_holiday(date(2016, 12, 27)) def test_oceania_shift_2009(self): holidays = self.cal.holidays_set(2009) # Boxing day is on saturday in 2009 # Boxing day is on 26th self.assertIn(date(2009, 12, 26), holidays) # Boxing day is observed on 28th assert self.cal.is_observed_holiday(date(2009, 12, 28)) calendra-7.9.0/calendra/tests/test_precomputed_astronomy.py000066400000000000000000000153701457013633400243020ustar00rootroot00000000000000import datetime import json import pathlib from unittest import TestCase from unittest.mock import MagicMock, call, patch, sentinel from freezegun import freeze_time from .. import precomputed_astronomy as mod class PreComputedAstronomyTest(TestCase): def test_year_interval(self): self.assertEqual(mod.YEAR_INTERVAL, 30) def test_time_zones(self): self.assertEqual(mod.TIME_ZONES, ( 'America/Santiago', 'Asia/Hong_Kong', 'Asia/Taipei', 'Asia/Tokyo', )) def test_pre_computed_pathes(self): self.assertEqual( mod.pre_computed_equinoxes_path, pathlib.Path(__file__).parent.parent / 'equinoxes.json.gz', ) self.assertEqual( mod.pre_computed_solar_terms_path, pathlib.Path(__file__).parent.parent / 'solar_terms.json.gz', ) @patch('calendra.skyfield_astronomy.solar_term') @patch('calendra.skyfield_astronomy.calculate_equinoxes') @patch('calendra.precomputed_astronomy.gzip.open') @patch('calendra.precomputed_astronomy.YEAR_INTERVAL', 1) @patch('calendra.precomputed_astronomy.TIME_ZONES', ('Europe/Paris',)) @freeze_time('2022-01-01') def test_create_astronomical_data(self, gzipopen, calculate_equinoxes, solar_term): equinoxes_file = MagicMock(name='equinoxes') equinoxes_file.__enter__.return_value = equinoxes_file solar_terms_file = MagicMock(name='solar_terms') solar_terms_file.__enter__.return_value = solar_terms_file gzipopen.side_effect = [equinoxes_file, solar_terms_file] calculate_equinoxes.side_effect = lambda year, timezone: ( datetime.date(year=year, month=2, day=15), datetime.date(year=year, month=3, day=16), ) solar_term.side_effect = lambda year, degrees, timezone: \ datetime.date(year=year, month=7, day=21) mod.create_astronomical_data() gzipopen.assert_has_calls([ call(mod.pre_computed_equinoxes_path, 'wb'), call(mod.pre_computed_solar_terms_path, 'wb'), ], any_order=True) expected_equinoxes_dict = { 'Europe/Paris': { '2021': ('2021-02-15', '2021-03-16'), '2022': ('2022-02-15', '2022-03-16'), '2023': ('2023-02-15', '2023-03-16'), } } equinoxes_file.write.assert_called_once_with( json.dumps(expected_equinoxes_dict).encode('utf-8') ) expected_solar_terms_dict = { 'Europe/Paris': { '2021': {str(i): '2021-07-21' for i in range(15, 360, 15)}, '2022': {str(i): '2022-07-21' for i in range(15, 360, 15)}, '2023': {str(i): '2023-07-21' for i in range(15, 360, 15)}, } } solar_terms_file.write.assert_called_once_with( json.dumps(expected_solar_terms_dict).encode('utf-8') ) @patch('calendra.precomputed_astronomy.gzip.decompress') @patch('calendra.precomputed_astronomy.pre_computed_equinoxes_path') def test_calculate_equinoxes(self, pre_computed_equinoxes_path, decompress): pre_computed_equinoxes_path.read_bytes.return_value = \ sentinel.some_equinoxes_bytes decompress.return_value = json.dumps({ 'Europe/Paris': { '2021': ('2021-02-15', '2021-03-16'), '2022': ('2022-02-15', '2022-03-16'), '2023': ('2023-02-15', '2023-03-16'), } }).encode('utf-8') with self.assertRaises(NotImplementedError): mod.calculate_equinoxes(2100, 'Europe/Paris') pre_computed_equinoxes_path.read_bytes.assert_called_once() pre_computed_equinoxes_path.reset_mock() decompress.assert_called_once_with(sentinel.some_equinoxes_bytes) decompress.reset_mock() with self.assertRaises(NotImplementedError): mod.calculate_equinoxes(2022, 'Europe/Berlin') pre_computed_equinoxes_path.read_bytes.assert_called_once() pre_computed_equinoxes_path.reset_mock() decompress.assert_called_once_with(sentinel.some_equinoxes_bytes) decompress.reset_mock() self.assertEqual(mod.calculate_equinoxes(2022, 'Europe/Paris'), ( datetime.date(year=2022, month=2, day=15), datetime.date(year=2022, month=3, day=16), )) pre_computed_equinoxes_path.read_bytes.assert_called_once() pre_computed_equinoxes_path.reset_mock() decompress.assert_called_once_with(sentinel.some_equinoxes_bytes) decompress.reset_mock() @patch('calendra.precomputed_astronomy.gzip.decompress') @patch('calendra.precomputed_astronomy.pre_computed_solar_terms_path') def test_sorted_term(self, pre_computed_solar_terms_path, decompress): pre_computed_solar_terms_path.read_bytes.return_value = \ sentinel.some_solar_terms_bytes decompress.return_value = json.dumps({ 'Europe/Paris': { '2021': {str(i): '2021-07-21' for i in range(15, 360, 15)}, '2022': {str(i): '2022-07-21' for i in range(15, 360, 15)}, '2023': {str(i): '2023-07-21' for i in range(15, 360, 15)}, } }).encode('utf-8') with self.assertRaises(ValueError): mod.solar_term(2022, 0, 'Europe/Paris') with self.assertRaises(ValueError): mod.solar_term(2022, 360, 'Europe/Paris') with self.assertRaises(ValueError): mod.solar_term(2022, 20, 'Europe/Paris') with self.assertRaises(NotImplementedError): mod.solar_term(2100, 45, 'Europe/Paris') pre_computed_solar_terms_path.read_bytes.assert_called_once() pre_computed_solar_terms_path.reset_mock() decompress.assert_called_once_with(sentinel.some_solar_terms_bytes) decompress.reset_mock() with self.assertRaises(NotImplementedError): mod.solar_term(2022, 90, 'Europe/Berlin') pre_computed_solar_terms_path.read_bytes.assert_called_once() pre_computed_solar_terms_path.reset_mock() decompress.assert_called_once_with(sentinel.some_solar_terms_bytes) decompress.reset_mock() self.assertEqual( mod.solar_term(2022, 90, 'Europe/Paris'), datetime.date(year=2022, month=7, day=21), ) pre_computed_solar_terms_path.read_bytes.assert_called_once() pre_computed_solar_terms_path.reset_mock() decompress.assert_called_once_with(sentinel.some_solar_terms_bytes) decompress.reset_mock() calendra-7.9.0/calendra/tests/test_registry.py000066400000000000000000000120451457013633400215040ustar00rootroot00000000000000from unittest import TestCase from ..core import Calendar from ..exceptions import ISORegistryError from ..registry import IsoRegistry class RegionCalendar(Calendar): 'Region' class SubRegionCalendar(Calendar): 'Sub Region' class NotACalendarClass: "Not a Calendar" class NonStandardRegistryTest(TestCase): def setUp(self): self.region = RegionCalendar self.subregion = SubRegionCalendar def test_region_registry(self): registry = IsoRegistry(load_standard_modules=False) self.assertEqual(0, len(registry.region_registry)) registry.register('RE', self.region) self.assertEqual(1, len(registry.region_registry)) self.assertEqual(RegionCalendar, registry.region_registry['RE']) def test_register_non_calendar(self): registry = IsoRegistry(load_standard_modules=False) with self.assertRaises(ISORegistryError): registry.register("NAC", NotACalendarClass) def test_get(self): registry = IsoRegistry(load_standard_modules=False) registry.register('RE', self.region) registry.register('RE-SR', self.subregion) calendar_class = registry.get('RE') self.assertEqual(calendar_class, RegionCalendar) # Subregion calendar_class = registry.get('RE-SR') self.assertEqual(calendar_class, SubRegionCalendar) # Unknown code/region self.assertIsNone(registry.get('XX')) def test_get_subregions(self): registry = IsoRegistry(load_standard_modules=False) registry.register('RE', self.region) registry.register('RE-SR', self.subregion) registry.register('OR-SR', self.subregion) subregions = registry.get_subregions('RE') # Only one sub-region here self.assertEqual(1, len(subregions)) self.assertIn('RE-SR', subregions) def test_get_calendars(self): registry = IsoRegistry(load_standard_modules=False) registry.register('RE', self.region) registry.register('RE-SR', self.subregion) registry.register('OR-SR', self.subregion) calendars = registry.get_calendars(['RE'], include_subregions=True) self.assertEqual(2, len(calendars)) self.assertIn('RE', calendars) self.assertIn('RE-SR', calendars) calendars = registry.get_calendars(['RE'], include_subregions=False) self.assertEqual(1, len(calendars)) self.assertIn('RE', calendars) def test_get_calendars_unknown(self): registry = IsoRegistry(load_standard_modules=False) registry.register('RE', self.region) calendars = registry.get_calendars(['XX']) self.assertEqual(calendars, {}) def test_get_calendars_with_subregions(self): registry = IsoRegistry(load_standard_modules=False) registry.register('RE', self.region) registry.register('RE2', self.region) registry.register('RE-SR', self.subregion) calendars = registry.get_calendars( ['RE2', "RE-SR"], include_subregions=True) self.assertEqual(2, len(calendars)) self.assertIn('RE2', calendars) self.assertIn('RE-SR', calendars) calendars = registry.get_calendars( ['RE2', "RE-SR"], include_subregions=False) self.assertEqual(2, len(calendars)) self.assertIn('RE2', calendars) self.assertIn('RE-SR', calendars) # Only a subregion calendars = registry.get_calendars(["RE-SR"], include_subregions=True) self.assertEqual(1, len(calendars)) self.assertIn('RE-SR', calendars) def test_get_calendars_empty_arg(self): registry = IsoRegistry(load_standard_modules=False) # 3 regions, one sub-region registry.register('RE', self.region) registry.register('RE2', self.region) registry.register('RE3', self.region) registry.register('RE-SR', self.subregion) # Empty arg, no subregions calendars = registry.get_calendars([], include_subregions=False) self.assertEqual(len(calendars), 3) self.assertEqual({"RE", "RE2", "RE3"}, set(calendars)) # Empty arg, with subregions calendars = registry.get_calendars([], include_subregions=True) self.assertEqual(len(calendars), 4) self.assertEqual({"RE", "RE2", "RE3", "RE-SR"}, set(calendars)) def test_get_calendars_no_arg(self): registry = IsoRegistry(load_standard_modules=False) # 3 regions, one sub-region registry.register('RE', self.region) registry.register('RE2', self.region) registry.register('RE3', self.region) registry.register('RE-SR', self.subregion) # Should be equivalent to [] + no subregions calendars = registry.get_calendars() self.assertEqual(len(calendars), 3) self.assertEqual({"RE", "RE2", "RE3"}, set(calendars)) # Should be equivalent to [] + include subregions calendars = registry.get_calendars(include_subregions=True) self.assertEqual(len(calendars), 4) self.assertEqual({"RE", "RE2", "RE3", "RE-SR"}, set(calendars)) calendra-7.9.0/calendra/tests/test_registry_africa.py000066400000000000000000000010621457013633400230060ustar00rootroot00000000000000from unittest import TestCase from ..africa import ( Algeria, Benin, IvoryCoast, Madagascar, SaoTomeAndPrincipe, SouthAfrica, ) from ..registry import registry class RegistryAfrica(TestCase): def test_africa(self): classes = set(registry.region_registry.values()) self.assertIn(Algeria, classes) self.assertIn(Benin, classes) self.assertIn(IvoryCoast, classes) self.assertIn(Madagascar, classes) self.assertIn(SaoTomeAndPrincipe, classes) self.assertIn(SouthAfrica, classes) calendra-7.9.0/calendra/tests/test_registry_america.py000066400000000000000000000070641457013633400231720ustar00rootroot00000000000000from unittest import TestCase # Brazil import from ..america import ( Brazil, BrazilAcre, BrazilAlagoas, BrazilAmapa, BrazilAmazonas, BrazilBahia, BrazilCeara, BrazilDistritoFederal, BrazilEspiritoSanto, BrazilGoias, BrazilMaranhao, BrazilMatoGrosso, BrazilMatoGrossoDoSul, BrazilPara, BrazilParaiba, BrazilPernambuco, BrazilPiaui, BrazilRioDeJaneiro, BrazilRioGrandeDoNorte, BrazilRioGrandeDoSul, BrazilRondonia, BrazilRoraima, BrazilSantaCatarina, BrazilSaoPauloState, BrazilSergipe, BrazilTocantins, ) # Canada territories from ..america import ( Canada, Ontario, Quebec, BritishColumbia, Alberta, Saskatchewan, Manitoba, NewBrunswick, NovaScotia, PrinceEdwardIsland, Newfoundland, Yukon, NorthwestTerritories, Nunavut, ) # Other american countries from ..america import ( Argentina, Chile, Colombia, Mexico, Panama, Paraguay ) from ..registry import registry class RegistryAmerica(TestCase): def _check_brazil_states(self, classes): self.assertIn(BrazilAcre, classes) self.assertIn(BrazilAlagoas, classes) self.assertIn(BrazilAmapa, classes) self.assertIn(BrazilAmazonas, classes) self.assertIn(BrazilBahia, classes) self.assertIn(BrazilCeara, classes) self.assertIn(BrazilDistritoFederal, classes) self.assertIn(BrazilEspiritoSanto, classes) self.assertIn(BrazilGoias, classes) self.assertIn(BrazilMaranhao, classes) self.assertIn(BrazilMatoGrosso, classes) self.assertIn(BrazilMatoGrossoDoSul, classes) self.assertIn(BrazilPara, classes) self.assertIn(BrazilParaiba, classes) self.assertIn(BrazilPernambuco, classes) self.assertIn(BrazilPiaui, classes) self.assertIn(BrazilRioDeJaneiro, classes) self.assertIn(BrazilRioGrandeDoNorte, classes) self.assertIn(BrazilRioGrandeDoSul, classes) self.assertIn(BrazilRondonia, classes) self.assertIn(BrazilRoraima, classes) self.assertIn(BrazilSantaCatarina, classes) self.assertIn(BrazilSaoPauloState, classes) self.assertIn(BrazilSergipe, classes) self.assertIn(BrazilTocantins, classes) def _check_canada_provinces(self, classes): self.assertIn(Ontario, classes) self.assertIn(Quebec, classes) self.assertIn(BritishColumbia, classes) self.assertIn(Alberta, classes) self.assertIn(Saskatchewan, classes) self.assertIn(Manitoba, classes) self.assertIn(NewBrunswick, classes) self.assertIn(NovaScotia, classes) self.assertIn(PrinceEdwardIsland, classes) self.assertIn(Newfoundland, classes) self.assertIn(Yukon, classes) self.assertIn(NorthwestTerritories, classes) self.assertIn(Nunavut, classes) def test_america(self): classes = set(registry.region_registry.values()) self.assertIn(Brazil, classes) self._check_brazil_states(classes) self.assertIn(Canada, classes) self._check_canada_provinces(classes) self.assertIn(Argentina, classes) self.assertIn(Chile, classes) self.assertIn(Colombia, classes) self.assertIn(Mexico, classes) self.assertIn(Panama, classes) self.assertIn(Paraguay, classes) def test_brazil_subregion(self): classes = set(registry.get_subregions('BR').values()) self._check_brazil_states(classes) def test_canada_subregion(self): classes = set(registry.get_subregions('CA').values()) self._check_canada_provinces(classes) calendra-7.9.0/calendra/tests/test_registry_asia.py000066400000000000000000000011611457013633400224760ustar00rootroot00000000000000from unittest import TestCase from ..asia import ( China, HongKong, Japan, Malaysia, Qatar, Singapore, SouthKorea, Taiwan, ) from ..registry import registry class RegistryAsia(TestCase): def test_asia(self): classes = set(registry.region_registry.values()) self.assertIn(China, classes) self.assertIn(HongKong, classes) self.assertIn(Japan, classes) self.assertIn(Malaysia, classes) self.assertIn(Qatar, classes) self.assertIn(Singapore, classes) self.assertIn(SouthKorea, classes) self.assertIn(Taiwan, classes) calendra-7.9.0/calendra/tests/test_registry_europe.py000066400000000000000000000115171457013633400230660ustar00rootroot00000000000000from unittest import TestCase from ..europe import ( Austria, Belgium, Bulgaria, Croatia, Cyprus, CzechRepublic, Estonia, Denmark, Finland, France, # FranceAlsaceMoselle, # TODO: Should we add it to the registry? Greece, Hungary, Iceland, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Monaco, Netherlands, Norway, Poland, Portugal, Romania, Russia, Slovakia, Slovenia, Sweden, UnitedKingdom, UnitedKingdomNorthernIreland, ) # Spain & regions from ..europe import ( Spain, Andalusia, Aragon, Catalonia, CastileAndLeon, CastillaLaMancha, CanaryIslands, Extremadura, Galicia, BalearicIslands, LaRioja, CommunityofMadrid, Murcia, Navarre, Asturias, BasqueCountry, Cantabria, ValencianCommunity, ) # Switzerland from ..europe import ( Switzerland, Aargau, AppenzellInnerrhoden, AppenzellAusserrhoden, Bern, BaselLandschaft, BaselStadt, Fribourg, Geneva, Glarus, Graubunden, Jura, Luzern, Neuchatel, Nidwalden, Obwalden, StGallen, Schaffhausen, Solothurn, Schwyz, Thurgau, Ticino, Uri, Vaud, Valais, Zug, Zurich ) # Germany from ..europe import ( Germany, BadenWurttemberg, Bavaria, Berlin, Brandenburg, Bremen, Hamburg, Hesse, MecklenburgVorpommern, LowerSaxony, NorthRhineWestphalia, RhinelandPalatinate, Saarland, Saxony, SaxonyAnhalt, SchleswigHolstein, Thuringia ) from ..registry import registry classes = set(registry.region_registry.values()) GERMANY_REGION_CLASSES = ( BadenWurttemberg, Bavaria, Berlin, Brandenburg, Bremen, Hamburg, Hesse, MecklenburgVorpommern, LowerSaxony, NorthRhineWestphalia, RhinelandPalatinate, Saarland, Saxony, SaxonyAnhalt, SchleswigHolstein, Thuringia ) SWITZERLAND_REGION_CLASSES = ( Aargau, AppenzellInnerrhoden, AppenzellAusserrhoden, Bern, BaselLandschaft, BaselStadt, Fribourg, Geneva, Glarus, Graubunden, Jura, Luzern, Neuchatel, Nidwalden, Obwalden, StGallen, Schaffhausen, Solothurn, Schwyz, Thurgau, Ticino, Uri, Vaud, Valais, Zug, Zurich ) SPAIN_REGION_CLASSES = ( Andalusia, Aragon, Catalonia, CastileAndLeon, CastillaLaMancha, CanaryIslands, Extremadura, Galicia, BalearicIslands, LaRioja, CommunityofMadrid, Murcia, Navarre, Asturias, BasqueCountry, Cantabria, ValencianCommunity, ) class RegistryEurope(TestCase): def test_europe(self): self.assertIn(Austria, classes) self.assertIn(Belgium, classes) self.assertIn(Bulgaria, classes) self.assertIn(Croatia, classes) self.assertIn(Cyprus, classes) self.assertIn(CzechRepublic, classes) self.assertIn(Estonia, classes) self.assertIn(Denmark, classes) self.assertIn(Finland, classes) self.assertIn(France, classes) self.assertIn(Greece, classes) self.assertIn(Hungary, classes) self.assertIn(Iceland, classes) self.assertIn(Ireland, classes) self.assertIn(Italy, classes) self.assertIn(Latvia, classes) self.assertIn(Lithuania, classes) self.assertIn(Luxembourg, classes) self.assertIn(Malta, classes) self.assertIn(Monaco, classes) self.assertIn(Netherlands, classes) self.assertIn(Norway, classes) self.assertIn(Poland, classes) self.assertIn(Portugal, classes) self.assertIn(Romania, classes) self.assertIn(Russia, classes) self.assertIn(Slovakia, classes) self.assertIn(Slovenia, classes) self.assertIn(Spain, classes) self.assertIn(Sweden, classes) self.assertIn(Switzerland, classes) self.assertIn(Vaud, classes) self.assertIn(Geneva, classes) self.assertIn(UnitedKingdom, classes) self.assertIn(UnitedKingdomNorthernIreland, classes) # Germany & Länders self.assertIn(Germany, classes) for klass in GERMANY_REGION_CLASSES: self.assertIn(klass, classes) for klass in SWITZERLAND_REGION_CLASSES: self.assertIn(klass, classes) for klass in SPAIN_REGION_CLASSES: self.assertIn(klass, classes) def test_germany_subregions(self): # Get all the subregions classes = set(registry.get_subregions('DE').values()) for klass in GERMANY_REGION_CLASSES: self.assertIn(klass, classes) def test_switzerland_subregions(self): # Get all the subregions classes = set(registry.get_subregions('CH').values()) for klass in SWITZERLAND_REGION_CLASSES: self.assertIn(klass, classes) def test_spain_subregions(self): # Get all the subregions classes = set(registry.get_subregions('ES').values()) for klass in SPAIN_REGION_CLASSES: self.assertIn(klass, classes) def test_slovenia_code(self): # Source: https://github.com/workalendar/workalendar/pull/291 self.assertEqual(registry.region_registry['SI'], Slovenia) calendra-7.9.0/calendra/tests/test_registry_oceania.py000066400000000000000000000022131457013633400231570ustar00rootroot00000000000000from unittest import TestCase from ..oceania import ( Australia, MarshallIslands, NewZealand, # Australian territories AustralianCapitalTerritory, NewSouthWales, NorthernTerritory, Queensland, SouthAustralia, Tasmania, # FIXME: there's no ISO code for this city. Shall we add it? # Hobart, Victoria, WesternAustralia ) from ..registry import registry AUSTRALIAN_TERRITORIES = ( AustralianCapitalTerritory, NewSouthWales, NorthernTerritory, Queensland, SouthAustralia, Tasmania, Victoria, WesternAustralia ) class RegistryOceania(TestCase): def test_oceania(self): classes = set(registry.region_registry.values()) self.assertIn(Australia, classes) self.assertIn(MarshallIslands, classes) self.assertIn(NewZealand, classes) for klass in AUSTRALIAN_TERRITORIES: self.assertIn(klass, classes) def test_australia_territories(self): # Get all the subregions classes = set(registry.get_subregions('AU').values()) for klass in AUSTRALIAN_TERRITORIES: self.assertIn(klass, classes) calendra-7.9.0/calendra/tests/test_registry_usa.py000066400000000000000000000065171457013633400223630ustar00rootroot00000000000000from unittest import TestCase from ..usa import ( UnitedStates, Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware, DistrictOfColumbia, Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, NewHampshire, NewJersey, NewMexico, NewYork, NorthCarolina, NorthDakota, Ohio, Oklahoma, Oregon, Pennsylvania, RhodeIsland, SouthCarolina, SouthDakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, WestVirginia, Wisconsin, Wyoming ) from ..registry import registry class RegistryUsa(TestCase): def _check_all_states(self, classes): self.assertIn(Alabama, classes) self.assertIn(Alaska, classes) self.assertIn(Arizona, classes) self.assertIn(Arkansas, classes) self.assertIn(California, classes) self.assertIn(Colorado, classes) self.assertIn(Connecticut, classes) self.assertIn(Delaware, classes) self.assertIn(DistrictOfColumbia, classes) self.assertIn(Florida, classes) self.assertIn(Georgia, classes) self.assertIn(Hawaii, classes) self.assertIn(Idaho, classes) self.assertIn(Illinois, classes) self.assertIn(Indiana, classes) self.assertIn(Iowa, classes) self.assertIn(Kansas, classes) self.assertIn(Kentucky, classes) self.assertIn(Louisiana, classes) self.assertIn(Maine, classes) self.assertIn(Maryland, classes) self.assertIn(Massachusetts, classes) self.assertIn(Michigan, classes) self.assertIn(Minnesota, classes) self.assertIn(Mississippi, classes) self.assertIn(Missouri, classes) self.assertIn(Montana, classes) self.assertIn(Nebraska, classes) self.assertIn(Nevada, classes) self.assertIn(NewHampshire, classes) self.assertIn(NewJersey, classes) self.assertIn(NewMexico, classes) self.assertIn(NewYork, classes) self.assertIn(NorthCarolina, classes) self.assertIn(NorthDakota, classes) self.assertIn(Ohio, classes) self.assertIn(Oklahoma, classes) self.assertIn(Oregon, classes) self.assertIn(Pennsylvania, classes) self.assertIn(RhodeIsland, classes) self.assertIn(SouthCarolina, classes) self.assertIn(SouthDakota, classes) self.assertIn(Tennessee, classes) self.assertIn(Texas, classes) self.assertIn(Utah, classes) self.assertIn(Vermont, classes) self.assertIn(Virginia, classes) self.assertIn(Washington, classes) self.assertIn(WestVirginia, classes) self.assertIn(Wisconsin, classes) self.assertIn(Wyoming, classes) def test_usa_world(self): classes = set(registry.region_registry.values()) self._check_all_states(classes) # On top of it, the core class self.assertIn(UnitedStates, classes) def test_usa_subregion(self): # Get all the subregions classes = set(registry.get_subregions('US').values()) self._check_all_states(classes) calendra-7.9.0/calendra/tests/test_scotland.py000066400000000000000000000447261457013633400214560ustar00rootroot00000000000000from datetime import date from unittest import TestCase import pytest from . import GenericCalendarTest from ..europe import ( Scotland, Aberdeen, Angus, Arbroath, Ayr, CarnoustieMonifieth, Clydebank, DumfriesGalloway, Dundee, EastDunbartonshire, Edinburgh, Elgin, Falkirk, Fife, Galashiels, Glasgow, Hawick, Inverclyde, Inverness, Kilmarnock, Lanark, Linlithgow, Lochaber, NorthLanarkshire, Paisley, Perth, ScottishBorders, SouthLanarkshire, Stirling, WestDunbartonshire, ) pytestmark = pytest.mark.filterwarnings('ignore:::calendra.europe.scotland') class GoodFridayTestMixin: def test_good_friday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 3, 30), holidays) class EasterMondayTestMixin: def test_easter_monday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 4, 2), holidays) class SpringHolidayFirstMondayAprilTestMixin: def test_spring_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 4, 2), holidays) class SpringHolidaySecondMondayAprilTestMixin: def test_spring_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 4, 9), holidays) class SpringHolidayLastMondayMayTestMixin: def test_spring_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 28), holidays) class FairHolidayLastMondayJuneTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 6, 25), holidays) class FairHolidayFirstMondayJulyTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 7, 2), holidays) class FairHolidaySecondMondayJulyTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 7, 9), holidays) class FairHolidayThirdMondayJulyTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 7, 16), holidays) class FairHolidayLastMondayJulyTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 7, 30), holidays) class FairHolidayFourthFridayJulyTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 7, 27), holidays) class FairHolidayFirstMondayAugustTestMixin: def test_fair_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 8, 6), holidays) class LateSummerTestMixin: def test_late_summer(self): # First monday of september holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 9, 3), holidays) class BattleStirlingBridgeTestMixin: def test_stirling(self): # Second monday of september holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 9, 10), holidays) class AutumnHolidayLastMondaySeptemberTestMixin: def test_autumn_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 9, 24), holidays) class AutumnHolidayFirstMondayOctoberTestMixin: def test_autumn_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 10, 1), holidays) class AutumnHolidaySecondMondayOctoberTestMixin: def test_autumn_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 10, 8), holidays) class AutumnHolidayThirdMondayOctoberTestMixin: def test_autumn_holiday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 10, 15), holidays) class SaintAndrewTestMixin: def test_saint_andrew(self): # St. Andrew's day happens on November 30th holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 11, 30), holidays) class VictoriaDayLastMondayMayTestMixin: def test_victoria_day(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 28), holidays) class SpringHolidayTuesdayAfterFirstMondayMayTestMixin: def test_spring_holiday_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 8), holidays) def test_spring_holiday_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 5, 2), holidays) class VictoriaDayFirstMondayJuneTestMixin: def test_victoria_day(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 6, 4), holidays) class VictoriaDayFourthMondayMayTestMixin: def test_victoria_day(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 28), holidays) class AyrGoldCupTestMixin: """ Ayr Gold cup - two holidays for Ayr and Kilmarnock """ def test_ayr_gold_cup(self): # Specific holidays in Ayr: # * 3rd Friday in September # * + the following Monday holidays = self.cal.holidays_set(2018) gold_cup_friday = date(2018, 9, 21) gold_cup_monday = date(2018, 9, 24) self.assertIn(gold_cup_friday, holidays) self.assertIn(gold_cup_monday, holidays) # Testing labels holidays = self.cal.holidays(2018) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[gold_cup_friday], "Ayr Gold Cup Friday") self.assertEqual(holidays_dict[gold_cup_monday], "Ayr Gold Cup Monday") # ----------------------------------------------------------------------------- class SpringHolidayTestCase(TestCase): def test_not_implemented_error(self): class FakeCalendar(Scotland): include_spring_holiday = True cal = FakeCalendar() with self.assertRaises(NotImplementedError): cal.holidays_set(2018) def test_correct_implementation(self): class FakeCalendar(Scotland): include_spring_holiday = True def get_spring_holiday(self, year): return date(year, 1, 1), "Spring Holiday" cal = FakeCalendar() self.assertTrue(cal.holidays_set(2018)) class VictoriaDayTestCase(TestCase): def test_not_implemented_error(self): class FakeCalendar(Scotland): include_victoria_day = True cal = FakeCalendar() with self.assertRaises(NotImplementedError): cal.holidays_set(2018) def test_correct_implementation(self): class FakeCalendar(Scotland): include_victoria_day = True def get_victoria_day(self, year): return date(year, 1, 1), "Victoria Day" cal = FakeCalendar() self.assertTrue(cal.holidays_set(2018)) class FairHolidayTestCase(TestCase): def test_not_implemented_error(self): class FakeCalendar(Scotland): include_fair_holiday = True cal = FakeCalendar() with self.assertRaises(NotImplementedError): cal.holidays_set(2018) def test_correct_implementation(self): class FakeCalendar(Scotland): include_fair_holiday = True def get_fair_holiday(self, year): return date(year, 1, 1), "Fair Holiday" cal = FakeCalendar() self.assertTrue(cal.holidays_set(2018)) class AutumnHolidayTestCase(TestCase): def test_not_implemented_error(self): class FakeCalendar(Scotland): include_autumn_holiday = True cal = FakeCalendar() with self.assertRaises(NotImplementedError): cal.holidays_set(2018) def test_correct_implementation(self): class FakeCalendar(Scotland): include_autumn_holiday = True def get_autumn_holiday(self, year): return date(year, 1, 1), "Autumn Holiday" cal = FakeCalendar() self.assertTrue(cal.holidays_set(2018)) class ScotlandTest(GenericCalendarTest): """ Generic Scotland test calendar. Scotland calendar includes the generic holidays + GoodFriday Some towns or cities don't necessarily observe it. """ cal_class = Scotland def test_init_warning(self): with pytest.warns(UserWarning, match="experimental"): self.cal_class() def test_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 1, 1), holidays) # New year's day self.assertIn(date(2018, 1, 2), holidays) # New year holiday self.assertIn(date(2018, 5, 7), holidays) # May day self.assertIn(date(2018, 12, 25), holidays) # XMas self.assertIn(date(2018, 12, 26), holidays) # Boxing day def test_good_friday(self): # By default, Good Friday is not a holiday holidays = self.cal.holidays_set(2018) self.assertNotIn(date(2018, 3, 30), holidays) class ScotlandAberdeenTest( GoodFridayTestMixin, FairHolidaySecondMondayJulyTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = Aberdeen class ScotlandAngusTest( SpringHolidaySecondMondayAprilTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, SaintAndrewTestMixin, ScotlandTest): cal_class = Angus class ScotlandArbroathTest( FairHolidayThirdMondayJulyTestMixin, ScotlandTest): cal_class = Arbroath class ScotlandAyrTest( GoodFridayTestMixin, EasterMondayTestMixin, SpringHolidayLastMondayMayTestMixin, AyrGoldCupTestMixin, ScotlandTest): cal_class = Ayr class ScotlandCarnoustieMonifiethTest( SpringHolidayFirstMondayAprilTestMixin, AutumnHolidayFirstMondayOctoberTestMixin, ScotlandTest): cal_class = CarnoustieMonifieth class ScotlandClydebankTest( SpringHolidayTuesdayAfterFirstMondayMayTestMixin, ScotlandTest): cal_class = Clydebank class ScotlandDumfriesGallowayTest(GoodFridayTestMixin, ScotlandTest): cal_class = DumfriesGalloway class ScotlandDundeeTest( SpringHolidayFirstMondayAprilTestMixin, VictoriaDayLastMondayMayTestMixin, FairHolidayLastMondayJulyTestMixin, AutumnHolidayFirstMondayOctoberTestMixin, ScotlandTest): cal_class = Dundee class ScotlandEastDunbartonshireTest( GoodFridayTestMixin, EasterMondayTestMixin, SpringHolidayLastMondayMayTestMixin, FairHolidayThirdMondayJulyTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = EastDunbartonshire class ScotlandEdinburghTest( GoodFridayTestMixin, EasterMondayTestMixin, ScotlandTest): cal_class = Edinburgh def test_edinburgh_spring_holiday(self): # Stated as the 3rd Monday in April... holidays = self.cal.holidays_set(2018) spring_holiday = date(2018, 4, 16) self.assertIn(spring_holiday, holidays) # ... except if it falls on Easter Monday # Then it's shifted to the previous week. # That was the case in 2017 holidays = self.cal.holidays(2017) holidays_dict = dict(holidays) easter_monday = date(2017, 4, 17) spring_holiday = date(2017, 4, 10) self.assertIn(easter_monday, holidays_dict) self.assertIn(spring_holiday, holidays_dict) self.assertEqual(holidays_dict[easter_monday], "Easter Monday") self.assertEqual(holidays_dict[spring_holiday], "Spring Holiday") def test_edinburgh_victoria_day(self): # The Monday strictly before May 24th holidays = self.cal.holidays_set(2018) victoria_day = date(2018, 5, 21) self.assertIn(victoria_day, holidays) # In 2010, May 24th was a monday, so Victoria Day is on 17th. holidays = self.cal.holidays_set(2010) victoria_day = date(2010, 5, 17) self.assertIn(victoria_day, holidays) def test_edinbirgh_autumn_holiday(self): # Third Monday in September holidays = self.cal.holidays_set(2018) autumn_holiday = date(2018, 9, 17) self.assertIn(autumn_holiday, holidays) class ScotlandElginTest( SpringHolidaySecondMondayAprilTestMixin, FairHolidayLastMondayJuneTestMixin, LateSummerTestMixin, AutumnHolidayThirdMondayOctoberTestMixin, ScotlandTest): cal_class = Elgin class ScotlandFalkirkTest( GoodFridayTestMixin, EasterMondayTestMixin, FairHolidayFirstMondayJulyTestMixin, BattleStirlingBridgeTestMixin, ScotlandTest): cal_class = Falkirk class ScotlandFifeTest( VictoriaDayFirstMondayJuneTestMixin, FairHolidayThirdMondayJulyTestMixin, AutumnHolidayThirdMondayOctoberTestMixin, SaintAndrewTestMixin, ScotlandTest): cal_class = Fife def test_spring_holiday(self): # Special computation rule, Fife has TWO spring holidays holidays = self.cal.holidays_set(2018) # First MON in April self.assertIn(date(2018, 4, 2), holidays) # First MON in June self.assertIn(date(2018, 6, 4), holidays) class ScotlandGalashiels(VictoriaDayFirstMondayJuneTestMixin, ScotlandTest): cal_class = Galashiels def test_braw_lads_gathering(self): # First friday in July holidays = self.cal.holidays_set(2018) braw_lads_gathering = date(2018, 7, 6) self.assertIn(braw_lads_gathering, holidays) class ScotlandGlasgowTest( EasterMondayTestMixin, SpringHolidayLastMondayMayTestMixin, FairHolidayThirdMondayJulyTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = Glasgow class ScotlandHawickTest(ScotlandTest): cal_class = Hawick def test_common_riding(self): # Friday after first monday in june & saturday holidays = self.cal.holidays_set(2018) common_riding_day1 = date(2018, 6, 8) common_riding_day2 = date(2018, 6, 9) self.assertIn(common_riding_day1, holidays) self.assertIn(common_riding_day2, holidays) # https://www.inverclyde.gov.uk/council-and-government/council-public-holidays # These documents say that Spring Holidays happened: # * on April 11th 2016 (second monday of April) # * on April 24th 2017 (last monday April) # * on April 16th 2018 (3rd monday April) # * on April 29th 2019 (last monday April) # ... # I think I'm becoming crazy class ScotlandInverclydeTest( GoodFridayTestMixin, EasterMondayTestMixin, LateSummerTestMixin, ScotlandTest): cal_class = Inverclyde def test_spring_holiday(self): # Special computation rule, Fife has TWO spring holidays holidays = self.cal.holidays_set(2018) # Last MON in April self.assertIn(date(2018, 4, 30), holidays) # First MON in June self.assertIn(date(2018, 6, 4), holidays) class ScotlandInvernessTest( SpringHolidayFirstMondayAprilTestMixin, FairHolidayFirstMondayJulyTestMixin, AutumnHolidayFirstMondayOctoberTestMixin, ScotlandTest): cal_class = Inverness def test_winter_february(self): # First MON of February holidays = self.cal.holidays_set(2018) winter_february = date(2018, 2, 5) self.assertIn(winter_february, holidays) def test_winter_march(self): # First MON of March holidays = self.cal.holidays_set(2018) winter_march = date(2018, 3, 5) self.assertIn(winter_march, holidays) def test_samhain_holiday(self): # First MON of November holidays = self.cal.holidays_set(2018) samhain_holiday = date(2018, 11, 5) self.assertIn(samhain_holiday, holidays) class ScotlandKilmarnockTest( GoodFridayTestMixin, EasterMondayTestMixin, AyrGoldCupTestMixin, ScotlandTest): cal_class = Kilmarnock class ScotlandLanarkTest(ScotlandTest): cal_class = Lanark def test_lanimer_day(self): # Second THU in June holidays = self.cal.holidays_set(2018) lanimer_day = date(2018, 6, 14) self.assertIn(lanimer_day, holidays) class ScotlandLinlithgowTest(ScotlandTest): cal_class = Linlithgow def test_linlithgow_marches(self): # Linlithgow marches is on TUE after the 2nd THU in June holidays = self.cal.holidays_set(2018) linlithgow_marches = date(2018, 6, 19) self.assertIn(linlithgow_marches, holidays) class ScotlandLochaberTest(ScotlandTest): cal_class = Lochaber def test_winter_holiday(self): # Winter holiday is on last MON in March. holidays = self.cal.holidays_set(2018) winter_holiday = date(2018, 3, 26) self.assertIn(winter_holiday, holidays) # Not the 4th, the *last* holidays = self.cal.holidays_set(2015) winter_holiday = date(2015, 3, 30) self.assertIn(winter_holiday, holidays) class ScotlandNorthLanarkshireTest( EasterMondayTestMixin, SpringHolidayLastMondayMayTestMixin, FairHolidayThirdMondayJulyTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = NorthLanarkshire class ScotlandPaisleyTest( GoodFridayTestMixin, EasterMondayTestMixin, VictoriaDayLastMondayMayTestMixin, FairHolidayFirstMondayAugustTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = Paisley class ScotlandPerthTest( SpringHolidayFirstMondayAprilTestMixin, VictoriaDayFourthMondayMayTestMixin, BattleStirlingBridgeTestMixin, AutumnHolidayFirstMondayOctoberTestMixin, ScotlandTest): cal_class = Perth class ScotlandScottishBordersTest( SpringHolidayFirstMondayAprilTestMixin, FairHolidayFourthFridayJulyTestMixin, AutumnHolidaySecondMondayOctoberTestMixin, SaintAndrewTestMixin, ScotlandTest): cal_class = ScottishBorders class ScotlandSouthLanarkshireTest( GoodFridayTestMixin, EasterMondayTestMixin, SpringHolidayLastMondayMayTestMixin, FairHolidayThirdMondayJulyTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = SouthLanarkshire class ScotlandStirlingTest( GoodFridayTestMixin, EasterMondayTestMixin, SpringHolidayTuesdayAfterFirstMondayMayTestMixin, BattleStirlingBridgeTestMixin, ScotlandTest): cal_class = Stirling class ScotlandWestDunbartonshireTest( GoodFridayTestMixin, EasterMondayTestMixin, AutumnHolidayLastMondaySeptemberTestMixin, ScotlandTest): cal_class = WestDunbartonshire calendra-7.9.0/calendra/tests/test_skyfield_astronomy.py000066400000000000000000000066501457013633400235660ustar00rootroot00000000000000import pytest from datetime import date from math import pi from unittest.mock import patch from skyfield.api import Loader from skyfield_data import get_skyfield_data_path from ..skyfield_astronomy import ( calculate_equinoxes, solar_term, newton_angle_function, ) def test_calculate_some_equinoxes(): assert calculate_equinoxes(2010) == (date(2010, 3, 20), date(2010, 9, 23)) assert calculate_equinoxes(2010, 'Asia/Taipei') == ( date(2010, 3, 21), date(2010, 9, 23) ) assert calculate_equinoxes(2013) == (date(2013, 3, 20), date(2013, 9, 22)) assert calculate_equinoxes(2014) == (date(2014, 3, 20), date(2014, 9, 23)) assert calculate_equinoxes(2020) == (date(2020, 3, 20), date(2020, 9, 22)) def test_qingming_festivals(): assert solar_term(2001, 15) == date(2001, 4, 4) assert solar_term(2001, 15, 'Asia/Taipei') == date(2001, 4, 5) assert solar_term(2011, 15) == date(2011, 4, 5) assert solar_term(2014, 15) == date(2014, 4, 4) assert solar_term(2016, 15) == date(2016, 4, 4) assert solar_term(2017, 15) == date(2017, 4, 4) def test_qingming_festivals_hk(): assert solar_term(2018, 15, 'Asia/Hong_Kong') == date(2018, 4, 5) assert solar_term(2019, 15, 'Asia/Hong_Kong') == date(2019, 4, 5) assert solar_term(2020, 15, 'Asia/Hong_Kong') == date(2020, 4, 4) assert solar_term(2021, 15, 'Asia/Hong_Kong') == date(2021, 4, 4) @pytest.fixture(scope='session') def params_newton_angle(): """ Session-scoped fixture to "cache" the newton angle func parameters """ load = Loader(get_skyfield_data_path()) ts = load.timescale() planets = load('de421.bsp') earth = planets['earth'] sun = planets['sun'] jan_first = ts.utc(date(2021, 1, 1)) t0 = ts.tt_jd(jan_first.tt).tt return t0, ts, earth, sun def test_newton_angle_function_normal_range(params_newton_angle): """ Test the newton angle func when the longitude is in the range [-pi, +pi]. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = pi assert newton_angle_function(t0, ts, 0, earth, sun) == -pi def test_newton_angle_function_above_pi(params_newton_angle): """ Test the newton angle function when the longitude is > +pi. This should not happen, but it was implemented in the function, so in order to make sure that the resulting angle is always in the range [-pi, +pi], we added these tests with those out of range values. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = pi + 0.1 expected = pytest.approx(-.1) assert newton_angle_function(t0, ts, 0, earth, sun) == expected def test_newton_angle_function_below_minus_pi(params_newton_angle): """ Test the newton angle function when the longitude is < -pi. This should not happen, but it was implemented in the function, so in order to make sure that the resulting angle is always in the range [-pi, +pi], we added these tests with those out of range values. """ t0, ts, earth, sun = params_newton_angle with patch('calendra.skyfield_astronomy.get_current_longitude') as patched: patched.return_value = -pi - 0.1 expected = pytest.approx(.1) assert newton_angle_function(t0, ts, 0, earth, sun) == expected calendra-7.9.0/calendra/tests/test_spain.py000066400000000000000000000333241457013633400207510ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..europe import ( Spain, Andalusia, Aragon, Catalonia, CastileAndLeon, CastillaLaMancha, CanaryIslands, Extremadura, Galicia, BalearicIslands, LaRioja, CommunityofMadrid, Murcia, Navarre, Asturias, BasqueCountry, Cantabria, ValencianCommunity ) class SpainTest(GenericCalendarTest): cal_class = Spain def test_common_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # New Year self.assertIn(date(2015, 1, 6), holidays) # Epiphany self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 5, 1), holidays) # Labour Day self.assertIn(date(2015, 8, 15), holidays) # Assumption self.assertIn(date(2015, 10, 12), holidays) # Nation Day self.assertIn(date(2015, 11, 1), holidays) # All Saints self.assertIn(date(2015, 12, 6), holidays) # Dia de la Constitución self.assertIn(date(2015, 12, 8), holidays) # Immaculate conception self.assertIn(date(2015, 12, 25), holidays) # Christmas def test_common_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 1, 1), holidays) # New Year self.assertIn(date(2016, 1, 6), holidays) # Epiphany self.assertIn(date(2016, 3, 25), holidays) # Good Friday self.assertIn(date(2016, 5, 1), holidays) # Labour Day self.assertIn(date(2016, 8, 15), holidays) # Assumption self.assertIn(date(2016, 10, 12), holidays) # Nation Day self.assertIn(date(2016, 11, 1), holidays) # All Saints self.assertIn(date(2016, 12, 6), holidays) # Dia de la Constitución self.assertIn(date(2016, 12, 8), holidays) # Immaculate conception self.assertIn(date(2016, 12, 25), holidays) # Christmas def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Día del trabajador") class AndalusiaTest(SpainTest): cal_class = Andalusia def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 2, 28), holidays) # Andalusian National Day self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 2, 28), holidays) # Andalusian National Day self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertEqual(len(holidays), 12) class AragonTest(SpainTest): cal_class = Aragon def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 4, 23), holidays) # Regional Day self.assertIn(date(2019, 12, 20), holidays) # Aragon Ombudsman Day self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 4, 23), holidays) # Regional Day self.assertIn(date(2020, 12, 20), holidays) # Aragon Ombudsman Day self.assertEqual(len(holidays), 13) class CastileAndLeonTest(SpainTest): cal_class = CastileAndLeon def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 4, 23), holidays) # Regional Day self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 4, 23), holidays) # Regional Day self.assertEqual(len(holidays), 12) class CastillaLaManchaTest(SpainTest): cal_class = CastillaLaMancha def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 5, 31), holidays) # Regional Day self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 5, 31), holidays) # Regional Day self.assertEqual(len(holidays), 12) class CanaryIslandsTest(SpainTest): cal_class = CanaryIslands def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 5, 30), holidays) # Regional Day self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 5, 30), holidays) # Regional Day self.assertEqual(len(holidays), 12) class CataloniaTest(SpainTest): cal_class = Catalonia def test_region_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 6), holidays) # Easter Monday # Diada nacional de Catalunya self.assertIn(date(2015, 9, 11), holidays) # La revetlla de Sant Joan, Nit de Sant Joan self.assertIn(date(2015, 6, 24), holidays) self.assertIn(date(2015, 12, 26), holidays) # Sant Esteve self.assertEqual(len(holidays), 14) def test_region_year_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 3, 28), holidays) # Easter Monday # Diada nacional de Catalunya self.assertIn(date(2016, 9, 11), holidays) # La revetlla de Sant Joan, Nit de Sant Joan self.assertIn(date(2016, 6, 24), holidays) self.assertIn(date(2016, 12, 26), holidays) # Sant Esteve self.assertEqual(len(holidays), 14) def test_boxing_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual(holidays[date(2020, 12, 26)], "Sant Esteve") class ExtremaduraTest(SpainTest): cal_class = Extremadura def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 9, 8), holidays) # Regional Day self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 9, 8), holidays) # Regional Day self.assertEqual(len(holidays), 12) class GaliciaTest(SpainTest): cal_class = Galicia def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 5, 17), holidays) # Galician Literature Day self.assertIn(date(2019, 7, 25), holidays) # Regional Day self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 5, 17), holidays) # Galician Literature Day self.assertIn(date(2020, 7, 25), holidays) # Regional Day self.assertEqual(len(holidays), 13) class BalearicIslandsTest(SpainTest): cal_class = BalearicIslands def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 1), holidays) # Balearic National Day self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 3, 1), holidays) # Balearic National Day self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertEqual(len(holidays), 13) class LaRiojaTest(SpainTest): cal_class = LaRioja def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 6, 9), holidays) # Dia de La Rioja self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 6, 9), holidays) # Dia de La Rioja self.assertEqual(len(holidays), 12) class CommunityofMadridTest(SpainTest): cal_class = CommunityofMadrid def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday # Fiesta de la Comunidad de Madrid self.assertIn(date(2019, 5, 2), holidays) self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday # Fiesta de la Comunidad de Madrid self.assertIn(date(2020, 5, 2), holidays) self.assertEqual(len(holidays), 12) class MurciaTest(SpainTest): cal_class = Murcia def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 19), holidays) # San José self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 6, 9), holidays) # Día de la Región de Murcia self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 3, 19), holidays) # San José self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 6, 9), holidays) # Día de la Región de Murcia self.assertEqual(len(holidays), 13) class NavarreTest(SpainTest): cal_class = Navarre def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertEqual(len(holidays), 12) class AsturiasTest(SpainTest): cal_class = Asturias def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 9, 8), holidays) # Día de Asturias self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 9, 8), holidays) # Día de Asturias self.assertEqual(len(holidays), 12) class BasqueCountryTest(SpainTest): cal_class = BasqueCountry def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday self.assertIn(date(2019, 4, 22), holidays) # Easter Monday self.assertIn(date(2019, 10, 25), holidays) # Euskadi Eguna self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 10, 25), holidays) # Euskadi Eguna self.assertEqual(len(holidays), 13) class CantabriaTest(SpainTest): cal_class = Cantabria def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 18), holidays) # Maundy/Holy Thursday # Día de Cantabria o Día de La Montaña self.assertIn(date(2019, 9, 15), holidays) self.assertEqual(len(holidays), 12) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 4, 9), holidays) # Maundy/Holy Thursday # Día de Cantabria o Día de La Montaña self.assertIn(date(2020, 9, 15), holidays) self.assertEqual(len(holidays), 12) class ValencianCommunityTest(SpainTest): cal_class = ValencianCommunity def test_region_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 19), holidays) # San José self.assertIn(date(2019, 4, 22), holidays) # Easter Monday # Dia de la Comunitat Valenciana self.assertIn(date(2019, 10, 9), holidays) self.assertEqual(len(holidays), 13) def test_region_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 3, 19), holidays) # San José self.assertIn(date(2020, 4, 13), holidays) # Easter Monday # Dia de la Comunitat Valenciana self.assertIn(date(2020, 10, 9), holidays) self.assertEqual(len(holidays), 13) calendra-7.9.0/calendra/tests/test_switzerland.py000066400000000000000000001343151457013633400222070ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..europe import ( Aargau, AppenzellInnerrhoden, AppenzellAusserrhoden, Bern, BaselLandschaft, BaselStadt, Fribourg, Geneva, Glarus, Graubunden, Jura, Luzern, Neuchatel, Nidwalden, Obwalden, StGallen, Schaffhausen, Solothurn, Schwyz, Thurgau, Ticino, Uri, Vaud, Valais, Zug, Zurich ) class AargauTest(GenericCalendarTest): cal_class = Aargau def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class AppenzellInnerrhodenTest(GenericCalendarTest): cal_class = AppenzellInnerrhoden def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class AppenzellAusserrhodenTest(GenericCalendarTest): cal_class = AppenzellAusserrhoden def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class BernTest(GenericCalendarTest): cal_class = Bern def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class BaselLandschaftTest(GenericCalendarTest): cal_class = BaselLandschaft def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class BaselStadtTest(GenericCalendarTest): cal_class = BaselStadt def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class FribourgTest(GenericCalendarTest): cal_class = Fribourg def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class GenevaTest(GenericCalendarTest): cal_class = Geneva def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day # Jeune Genevois, only in Geneva self.assertIn(date(2020, 9, 10), holidays) self.assertIn(date(2020, 12, 25), holidays) # XMas # Restoration day - Geneva self.assertIn(date(2020, 12, 31), holidays) def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day # Jeune Genevois, only in Geneva self.assertIn(date(2021, 9, 9), holidays) self.assertIn(date(2021, 12, 25), holidays) # XMas # Restoration day - Geneva self.assertIn(date(2021, 12, 31), holidays) class GlarusTest(GenericCalendarTest): cal_class = Glarus def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds # Only in Glarus/Glaris self.assertIn(date(2020, 4, 3), holidays) # Näfels Day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds # Only in Glarus/Glaris self.assertIn(date(2021, 4, 3), holidays) # Näfels Day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class GraubundenTest(GenericCalendarTest): cal_class = Graubunden def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 6), holidays) # Epiphany self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class JuraTest(GenericCalendarTest): cal_class = Jura def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi # Independance day - Only in Jura self.assertIn(date(2020, 6, 23), holidays) self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 25), holidays) # XMas def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi # Independance day - Only in Jura self.assertIn(date(2021, 6, 23), holidays) self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 25), holidays) # XMas class LuzernTest(GenericCalendarTest): cal_class = Luzern def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 1, 6), holidays) # Epiphany self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class NeuchatelTest(GenericCalendarTest): cal_class = Neuchatel def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertNotIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 3, 1), holidays) # Republic Day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day # Lundi du Jeûne - Only in Vaud/Neuchatel self.assertIn(date(2020, 9, 21), holidays) self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertNotIn(date(2022, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertNotIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 3, 1), holidays) # Republic Day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day # Lundi du Jeûne - Only in Vaud/Neuchatel self.assertIn(date(2021, 9, 20), holidays) self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertNotIn(date(2022, 12, 26), holidays) # St Stephen's day def test_year_2022(self): holidays = self.cal.holidays_set(2022) # Only when Christmas is on Sunday self.assertIn(date(2022, 12, 26), holidays) # St Stephen's day def test_year_2023(self): holidays = self.cal.holidays_set(2023) # Only when New year is on Sunday self.assertIn(date(2023, 1, 2), holidays) # Berchtolds class NidwaldenTest(GenericCalendarTest): cal_class = Nidwalden def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class ObwaldenTest(GenericCalendarTest): cal_class = Obwalden def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 9, 25), holidays) # Saint Nicholas of Flüe self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 9, 25), holidays) # Saint Nicholas of Flüe self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class StGallenTest(GenericCalendarTest): cal_class = StGallen def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class SchaffhausenTest(GenericCalendarTest): cal_class = Schaffhausen def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class SolothurnTest(GenericCalendarTest): cal_class = Solothurn def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class SchwyzTest(GenericCalendarTest): cal_class = Schwyz def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 6), holidays) # Epiphany self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class ThurgauTest(GenericCalendarTest): cal_class = Thurgau def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class TicinoTest(GenericCalendarTest): cal_class = Ticino def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi # St Peter & St Paul - Only in Ticino self.assertIn(date(2020, 6, 29), holidays) self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 6), holidays) # Epiphany self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi # St Peter & St Paul - Only in Ticino self.assertIn(date(2021, 6, 29), holidays) self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class UriTest(GenericCalendarTest): cal_class = Uri def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 6), holidays) # Epiphany self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 6), holidays) # Epiphany self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class VaudTest(GenericCalendarTest): cal_class = Vaud def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day # Lundi du Jeûne - Only in Vaud/Neuchatel self.assertIn(date(2020, 9, 21), holidays) self.assertIn(date(2020, 12, 25), holidays) # XMas def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day # Lundi du Jeûne - Only in Vaud/Neuchatel self.assertIn(date(2021, 9, 20), holidays) self.assertIn(date(2021, 12, 25), holidays) # XMas class ValaisTest(GenericCalendarTest): cal_class = Valais def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 3, 19), holidays) # St Joseph self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 3, 19), holidays) # St Joseph self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas class ZugTest(GenericCalendarTest): cal_class = Zug def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 6, 11), holidays) # Corpus Christi self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 8, 15), holidays) # Assumption self.assertIn(date(2020, 11, 1), holidays) # All Saints self.assertIn(date(2020, 12, 8), holidays) # Immaculate conception self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 6, 3), holidays) # Corpus Christi self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 8, 15), holidays) # Assumption self.assertIn(date(2021, 11, 1), holidays) # All Saints self.assertIn(date(2021, 12, 8), holidays) # Immaculate conception self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day class ZurichTest(GenericCalendarTest): cal_class = Zurich def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New years day self.assertIn(date(2020, 1, 2), holidays) # Berchtolds self.assertIn(date(2020, 4, 10), holidays) # Good Friday self.assertIn(date(2020, 4, 13), holidays) # Easter Monday self.assertIn(date(2020, 5, 1), holidays) # Labour Day self.assertIn(date(2020, 5, 21), holidays) # Ascension day self.assertIn(date(2020, 6, 1), holidays) # Whit Monday self.assertIn(date(2020, 8, 1), holidays) # Swiss National Day self.assertIn(date(2020, 12, 25), holidays) # XMas self.assertIn(date(2020, 12, 26), holidays) # St Stephen's day def test_year_2021(self): holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 1, 1), holidays) # New years day self.assertIn(date(2021, 1, 2), holidays) # Berchtolds self.assertIn(date(2021, 4, 2), holidays) # Good Friday self.assertIn(date(2021, 4, 5), holidays) # Easter Monday self.assertIn(date(2021, 5, 1), holidays) # Labour Day self.assertIn(date(2021, 5, 13), holidays) # Ascension day self.assertIn(date(2021, 5, 24), holidays) # Whit Monday self.assertIn(date(2021, 8, 1), holidays) # Swiss National Day self.assertIn(date(2021, 12, 25), holidays) # XMas self.assertIn(date(2021, 12, 26), holidays) # St Stephen's day calendra-7.9.0/calendra/tests/test_turkey.py000066400000000000000000000064511457013633400211630ustar00rootroot00000000000000from datetime import date from . import GenericCalendarTest from ..europe import Turkey class TurkeyTest(GenericCalendarTest): cal_class = Turkey def test_year_new_year_shift(self): holidays = self.cal.holidays_set(2012) self.assertIn(date(2012, 1, 1), holidays) self.assertNotIn(date(2012, 1, 2), holidays) holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) self.assertNotIn(date(2013, 1, 2), holidays) def test_year_2014(self): holidays = self.cal.holidays_set(2014) # Fixed days section: # 1. New years Day self.assertIn(date(2014, 1, 1), holidays) # 2. National Sovereignty and Children's Day self.assertIn(date(2014, 4, 23), holidays) # 3. Labor and Solidarity Day self.assertIn(date(2014, 5, 1), holidays) # 4. Commemoration of Atatürk, Youth and Sports Day self.assertIn(date(2014, 5, 19), holidays) # 5. Democracy and National Unity Day self.assertIn(date(2014, 7, 15), holidays) # 6. Victory Day self.assertIn(date(2014, 8, 30), holidays) # 7. Republic Day self.assertIn(date(2014, 10, 29), holidays) def test_year_2015(self): holidays = self.cal.holidays_set(2015) # Fixed days section: # 1. New years Day self.assertIn(date(2015, 1, 1), holidays) # 2. National Sovereignty and Children's Day self.assertIn(date(2015, 4, 23), holidays) # 3. Labor and Solidarity Day self.assertIn(date(2015, 5, 1), holidays) # 4. Commemoration of Atatürk, Youth and Sports Day self.assertIn(date(2015, 5, 19), holidays) # 5. Democracy and National Unity Day self.assertIn(date(2015, 7, 15), holidays) # 6. Victory Day self.assertIn(date(2015, 8, 30), holidays) # 7. Republic Day self.assertIn(date(2015, 10, 29), holidays) def test_year_2019(self): holidays = self.cal.holidays_set(2019) # Fixed days section: # 1. New years Day self.assertIn(date(2019, 1, 1), holidays) # 2. National Sovereignty and Children's Day self.assertIn(date(2019, 4, 23), holidays) # 3. Labor and Solidarity Day self.assertIn(date(2019, 5, 1), holidays) # 4. Commemoration of Atatürk, Youth and Sports Day self.assertIn(date(2019, 5, 19), holidays) # 5. Democracy and National Unity Day self.assertIn(date(2019, 7, 15), holidays) # 6. Victory Day self.assertIn(date(2019, 8, 30), holidays) # 7. Republic Day self.assertIn(date(2019, 10, 29), holidays) # Religious days # Ramadan Feast - 3 days self.assertIn(date(2019, 6, 4), holidays) self.assertIn(date(2019, 6, 5), holidays) self.assertIn(date(2019, 6, 6), holidays) # Ramadan Feast - 4 days self.assertIn(date(2019, 8, 11), holidays) self.assertIn(date(2019, 8, 12), holidays) self.assertIn(date(2019, 8, 13), holidays) self.assertIn(date(2019, 8, 14), holidays) def test_labour_day_label(self): holidays = self.cal.holidays(2020) holidays = dict(holidays) self.assertEqual( holidays[date(2020, 5, 1)], "Labor and Solidarity Day") calendra-7.9.0/calendra/tests/test_usa.py000066400000000000000000002324701457013633400204320ustar00rootroot00000000000000from unittest import skip from datetime import date import pytest from . import GenericCalendarTest from ..usa import ( UnitedStates, Alabama, AlabamaBaldwinCounty, AlabamaMobileCounty, AlabamaPerryCounty, Arkansas, Alaska, Arizona, # California and others California, CaliforniaEducation, CaliforniaBerkeley, CaliforniaSanFrancisco, CaliforniaWestHollywood, # Florida and others Florida, FloridaLegal, FloridaCircuitCourts, FloridaMiamiDade, Colorado, Connecticut, Delaware, DistrictOfColumbia, Georgia, Hawaii, Indiana, Illinois, Idaho, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, Minnesota, Michigan, Mississippi, Missouri, Montana, Nebraska, Nevada, NewHampshire, NewJersey, NewMexico, NewYork, NorthCarolina, NorthDakota, Ohio, Oklahoma, Oregon, Pennsylvania, RhodeIsland, SouthCarolina, SouthDakota, Tennessee, TexasBase, Texas, Utah, Vermont, Virginia, Washington, WestVirginia, Wisconsin, Wyoming, # Other territories, cities... AmericanSamoa, ChicagoIllinois, Guam, SuffolkCountyMassachusetts, FederalReserveSystem, ) class UnitedStatesTest(GenericCalendarTest): cal_class = UnitedStates def test_martin_luther_king_day(self): # All States observe this day, but it started in 1985 only. holidays = self.cal.holidays_set(2013) mlk_day = self.cal.get_martin_luther_king_date(2013) self.assertEqual(date(2013, 1, 21), mlk_day) self.assertIn(mlk_day, holidays) holidays = self.cal.holidays_set(2014) mlk_day = self.cal.get_martin_luther_king_date(2014) self.assertEqual(date(2014, 1, 20), mlk_day) self.assertIn(mlk_day, holidays) # Shifted in 2015 holidays = self.cal.holidays_set(2015) mlk_day = self.cal.get_martin_luther_king_date(2015) self.assertEqual(date(2015, 1, 19), mlk_day) self.assertIn(mlk_day, holidays) # Let's get into the past holidays = self.cal.holidays_set(1986) mlk_day = self.cal.get_martin_luther_king_date(1986) self.assertEqual(date(1986, 1, 20), mlk_day) self.assertIn(mlk_day, holidays) holidays = self.cal.holidays_set(1985) mlk_day = self.cal.get_martin_luther_king_date(1985) self.assertEqual(date(1985, 1, 21), mlk_day) self.assertIn(mlk_day, holidays) # No MLK Day before 1985 # 3rd Monday of January was the 16th holidays = self.cal.holidays_set(1984) self.assertNotIn(date(1984, 1, 16), holidays) with self.assertRaises(ValueError): self.cal.get_martin_luther_king_date(1984) def test_mlk_label(self): _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual(label, "Birthday of Martin Luther King, Jr.") def test_federal_year_2013(self): holidays = self.cal.holidays_set(2013) self.assertIn(date(2013, 1, 1), holidays) # New Year self.assertIn(date(2013, 5, 27), holidays) # Memorial day self.assertIn(date(2013, 7, 4), holidays) # Nation day self.assertIn(date(2013, 9, 2), holidays) # Labour day self.assertIn(date(2013, 11, 11), holidays) # Armistice self.assertIn(date(2013, 11, 28), holidays) # Thanskgiving self.assertIn(date(2013, 12, 25), holidays) # Christmas def test_independence_day_nearest_weekday(self): """ Independence Day should shift to the nearest weekday. """ observed = self.cal.observed_holidays(2010) self.assertIn(date(2010, 7, 5), observed) observed = self.cal.observed_holidays(2011) self.assertIn(date(2011, 7, 4), observed) observed = self.cal.observed_holidays(2015) self.assertIn(date(2015, 7, 3), observed) def test_presidential_year(self): self.assertTrue(UnitedStates.is_presidential_year(2012)) self.assertFalse(UnitedStates.is_presidential_year(2013)) self.assertFalse(UnitedStates.is_presidential_year(2014)) self.assertFalse(UnitedStates.is_presidential_year(2015)) self.assertTrue(UnitedStates.is_presidential_year(2016)) def test_election_day(self): # Election day is: # the Tuesday next after the first Monday in the month of November self.assertEqual(date(2013, 11, 5), self.cal.get_election_date(2013)) self.assertEqual(date(2014, 11, 4), self.cal.get_election_date(2014)) self.assertEqual(date(2015, 11, 3), self.cal.get_election_date(2015)) self.assertEqual(date(2016, 11, 8), self.cal.get_election_date(2016)) self.assertEqual(date(2017, 11, 7), self.cal.get_election_date(2017)) self.assertEqual(date(2018, 11, 6), self.cal.get_election_date(2018)) self.assertEqual(date(2019, 11, 5), self.cal.get_election_date(2019)) self.assertEqual(date(2020, 11, 3), self.cal.get_election_date(2020)) def test_election_day_label(self): _, label = self.cal.get_election_day(2017) self.assertEqual(label, "Election Day") def test_federal_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 1), holidays) # New Year self.assertIn(date(2014, 5, 26), holidays) # Memorial day self.assertIn(date(2014, 7, 4), holidays) # Nation day self.assertIn(date(2014, 9, 1), holidays) # Labour day self.assertIn(date(2014, 11, 11), holidays) # Armistice self.assertIn(date(2014, 11, 27), holidays) # Thanskgiving self.assertIn(date(2014, 12, 25), holidays) # XMas def test_federal_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 1), holidays) # New Year self.assertIn(date(2015, 5, 25), holidays) # Memorial day self.assertIn(date(2015, 7, 4), holidays) # Nation day self.assertIn(date(2015, 9, 7), holidays) # Labour day self.assertIn(date(2015, 11, 11), holidays) # Armistice self.assertIn(date(2015, 11, 26), holidays) # Thanskgiving self.assertIn(date(2015, 12, 25), holidays) # XMas def test_federal_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertNotIn(date(2017, 12, 27), holidays) # XMas def test_columbus_day(self): holidays = self.cal.holidays_set(2017) # Columbus Day is included here self.assertIn(date(2017, 10, 9), holidays) def test_columbus_day_label(self): _, label = self.cal.get_columbus_day(2017) self.assertEqual(label, "Columbus Day") def test_presidential_day(self): # Washington's birthday, or sometimes called otherwise, may not # be included. holidays = self.cal.holidays_set(2017) day, _ = self.cal.get_presidents_day(2017) # Washington's birthday is included here self.assertIn(day, holidays) def test_president_day_label(self): _, label = self.cal.get_presidents_day(2017) self.assertEqual(label, "Washington's Birthday") def test_get_inauguration_date(self): self.assertEqual( date(2017, 1, 20), self.cal.get_inauguration_date(2017)) # Not an "inauguration day" year with self.assertRaises(ValueError): self.cal.get_inauguration_date(2016) with self.assertRaises(ValueError): self.cal.get_inauguration_date(2015) with self.assertRaises(ValueError): self.cal.get_inauguration_date(2014) # Shifted to MON, since the 20th was on SUN self.assertEqual( date(2013, 1, 21), self.cal.get_inauguration_date(2013)) # 2009, back to normal self.assertEqual( date(2009, 1, 20), self.cal.get_inauguration_date(2009)) def test_inauguration_day(self): # NOTE: 2013 test is not relevant, it's the same day as MLK day. # NOTE: 1985 test is not relevant, it's the same day as MLK day. # By default, it's not a public holiday self.assertNotIn( self.cal.get_inauguration_date(2017), self.cal.holidays_set(2017) ) self.assertNotIn( self.cal.get_inauguration_date(2009), self.cal.holidays_set(2009) ) self.assertNotIn( self.cal.get_inauguration_date(1957), self.cal.holidays_set(1957) ) def test_election_day_inclusion(self): # By default, election day is not included for year in range(2013, 2020): holidays = self.cal.holidays_set(year) self.assertNotIn(self.cal.get_election_date(year), holidays) def test_thanksgiving_friday(self): day, _ = self.cal.get_thanksgiving_friday(2017) self.assertEqual(day, date(2017, 11, 24)) day, _ = self.cal.get_thanksgiving_friday(2018) self.assertEqual(day, date(2018, 11, 23)) day, _ = self.cal.get_thanksgiving_friday(2019) self.assertEqual(day, date(2019, 11, 29)) def test_thanksgiving_friday_label(self): _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Thanksgiving Friday") def test_national_memorial_label(self): _, label = self.cal.get_national_memorial_day(2017) self.assertEqual(label, "Memorial Day") def test_veterans_label(self): _, label = self.cal.get_veterans_day(2017) self.assertEqual(label, "Veterans Day") def test_mardi_gras(self): year = 2017 day = self.cal.get_fat_tuesday(year) holidays = self.cal.holidays_set(year) self.assertNotIn(day, holidays) class NoColumbus: """ Some States don't include Columbus Day: * Alaska * Arkansas * California * Delaware """ def test_columbus_day(self): # This overrides UnitedStates.test_columbus_day holidays = self.cal.holidays_set(2017) # Columbus Day... Not included self.assertNotIn(date(2017, 10, 9), holidays) class NoPresidentialDay: """ Washington's birthday is not included in Delaware calendar. """ def test_presidential_day(self): # This function *overwrites* UnitedStates.test_presidential_day holidays = self.cal.holidays_set(2017) day, _ = self.cal.get_presidents_day(2017) # Washington's birthday not included here self.assertNotIn(day, holidays) class InaugurationDay: """ When Inauguration Day is a public holiday """ def test_inauguration_day(self): # This method overwrites UnitedStatesTest.test_inauguration_day self.assertIn( self.cal.get_inauguration_date(2017), self.cal.holidays_set(2017) ) # NOTE: 2013 test is not relevant, it's the same as MLK Day self.assertIn( self.cal.get_inauguration_date(2009), self.cal.holidays_set(2009) ) # NOTE: 1985 is not relevant, it's the same as MLK Day class ElectionDayEvenYears: """ Some state include the election day on even years """ def test_election_day_inclusion(self): # This method overwrites UnitedStates.test_election_day_inclusion() # Election Day is a public holiday on even years. holidays = self.cal.holidays_set(2014) self.assertIn(self.cal.get_election_date(2014), holidays) # Odd year -- not included holidays = self.cal.holidays_set(2015) self.assertNotIn(self.cal.get_election_date(2015), holidays) # Even year holidays = self.cal.holidays_set(2016) self.assertIn(self.cal.get_election_date(2016), holidays) # Odd year -- not included holidays = self.cal.holidays_set(2017) self.assertNotIn(self.cal.get_election_date(2017), holidays) class ElectionDayPresidentialYears: """ Some state include the election day on presidential years """ def test_election_day_inclusion(self): # This method overwrites UnitedStates.test_election_day_inclusion() # Election Day is a public holiday presidential years. # not included holidays = self.cal.holidays_set(2014) self.assertNotIn(self.cal.get_election_date(2014), holidays) # not included holidays = self.cal.holidays_set(2015) self.assertNotIn(self.cal.get_election_date(2015), holidays) # 2016 election holidays = self.cal.holidays_set(2016) self.assertIn(self.cal.get_election_date(2016), holidays) # not included holidays = self.cal.holidays_set(2017) self.assertNotIn(self.cal.get_election_date(2017), holidays) class ElectionDayEveryYear: """ Some State include election day on every year """ def test_election_day_inclusion(self): # Election day is included *every year* for year in range(2013, 2020): holidays = self.cal.holidays_set(year) self.assertIn(self.cal.get_election_date(year), holidays) class IncludeMardiGras: """ Louisiana and some areas (Alabama Counties) include Mardi Gras """ def test_mardi_gras(self): year = 2017 day = self.cal.get_fat_tuesday(year) holidays = self.cal.holidays(year) holidays_dict = dict(holidays) self.assertIn(day, holidays_dict) self.assertEqual(holidays_dict[day], "Mardi Gras") class AlabamaTest(UnitedStatesTest): cal_class = Alabama def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label # Martin Luther King day is renamed in Alabama _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual(label, "Robert E. Lee/Martin Luther King Birthday") def test_president_day_label(self): # Overwrite UnitedStatesTest.test_president_day_label # Presidents day is renamed in Alabama _, label = self.cal.get_presidents_day(2017) self.assertEqual(label, "George Washington/Thomas Jefferson Birthday") def test_columbus_day_label(self): # Overwrite UnitedStatesTest.test_columbus_day_label # Columbus day is renamed in Alabama _, label = self.cal.get_columbus_day(2017) self.assertEqual( label, "Columbus Day / Fraternal Day / American Indian Heritage Day") def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 28), holidays) # Confederate Memorial Day self.assertIn(date(2014, 6, 2), holidays) # Jefferson Davis' birthday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 27), holidays) # Confederate Memorial Day self.assertIn(date(2015, 6, 1), holidays) # Jefferson Davis' birthday class AlabamaBaldwinCountyTest(IncludeMardiGras, AlabamaTest): cal_class = AlabamaBaldwinCounty class AlabamaMobileCountyTest(IncludeMardiGras, AlabamaTest): cal_class = AlabamaMobileCounty class AlabamaPerryCountyTest(AlabamaTest): cal_class = AlabamaPerryCounty def test_county_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 11, 13), holidays) # Obama Day class AlaskaTest(NoColumbus, UnitedStatesTest): cal_class = Alaska def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 3, 31), holidays) # Seward's Day self.assertIn(date(2014, 10, 18), holidays) # Alaska Day observed = self.cal.observed_holidays(2014) # Alaska Day is on SAT, shift to FRI self.assertIn(date(2014, 10, 17), observed) def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 3, 30), holidays) # Seward's Day self.assertIn(date(2015, 10, 18), holidays) # Alaska Day observed = self.cal.observed_holidays(2015) # Alaska day is on SUN: shifted to MON self.assertIn(date(2015, 10, 19), observed) def test_state_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 3, 27), holidays) # Seward's Day self.assertIn(date(2017, 10, 18), holidays) # Alaska Day observed = self.cal.observed_holidays(2017) # Alaska day is on WED: no shift self.assertNotIn(date(2017, 10, 19), observed) self.assertNotIn(date(2017, 10, 17), observed) class ArizonaTest(UnitedStatesTest): cal_class = Arizona def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label # Martin Luther King day is renamed in Arizona _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual(label, "Dr. Martin Luther King Jr./Civil Rights Day") def test_president_day_label(self): # Overwrite UnitedStatesTest.test_president_day_label # Presidents day is renamed in Arizona _, label = self.cal.get_presidents_day(2017) self.assertEqual(label, "Lincoln/Washington Presidents' Day") class ArkansasTest(NoColumbus, UnitedStatesTest): cal_class = Arkansas def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 12, 24), holidays) # XMas Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 12, 24), holidays) # XMas Eve def test_christmas_2016(self): holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 12, 24), holidays) # XMas Eve observed = self.cal.observed_holidays(2016) self.assertIn(date(2016, 12, 23), observed) # XMas Eve shifted def test_president_day_label(self): # Overwrite UnitedStatesTest.test_president_day_label # Presidents day is renamed in Arkansas _, label = self.cal.get_presidents_day(2017) self.assertEqual( label, "George Washington's Birthday and Daisy Gatson Bates Day" ) class CaliforniaTest(NoColumbus, UnitedStatesTest): cal_class = California def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 3, 31), holidays) # Cesar Chavez Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 3, 31), holidays) # Cesar Chavez Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_state_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 3, 31), holidays) # Cesar Chavez Day # Happens on SAT, but is not shifted self.assertNotIn(date(2018, 3, 30), holidays) self.assertIn(date(2018, 11, 23), holidays) # Thanksgiving Friday def test_state_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 31), holidays) # Cesar Chavez Day self.assertIn(date(2019, 4, 1), holidays) # Cesar Chavez Day Shift self.assertIn(date(2019, 11, 29), holidays) # Thanksgiving Friday def test_chavez_no_duplicates(self): # See issue #528 holidays = self.cal.holidays(2019) days = [item[0] for item in holidays] assert days for day in days: assert days.count(day) == 1, f"{day} is duplicated" class CaliforniaEducationTest(CaliforniaTest): cal_class = CaliforniaEducation def test_specific_lincoln_birthday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 2, 12), holidays) # Lincoln's Birthday holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 2, 12), holidays) # Lincoln's Birthday # Lincoln's Birthday wasn't included in 2009 holidays = self.cal.holidays_set(2009) self.assertNotIn(date(2009, 2, 12), holidays) def test_specific_native_american_day(self): # Native American Day occurs on the 4th MON of September holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 9, 24), holidays) # Native American Day holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 9, 23), holidays) # Native American Day # Like California, except that it has: # * No Chavez Day, # * Includes Columbus day, but relabels it. # * Adds Lincoln's Birthday. class CaliforniaBerkeleyTest(UnitedStatesTest): cal_class = CaliforniaBerkeley def test_state_year_2014(self): # Overwriting CaliforniaTest, there's no Chavez Day for Berkeley holidays = self.cal.holidays_set(2014) self.assertNotIn(date(2014, 3, 31), holidays) # NO Cesar Chavez Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): # Overwriting CaliforniaTest, there's no Chavez Day for Berkeley holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 3, 31), holidays) # NO Cesar Chavez Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_specific_lincoln_birthday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 2, 12), holidays) # Lincoln's Birthday holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 2, 12), holidays) # Lincoln's Birthday def test_specific_malcomx_birthday(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 19), holidays) # Malcom X Day holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 5, 19), holidays) # Malcom X Day def test_columbus_day_label(self): # Overwrite UnitedStatesTest.test_columbus_day_label _, label = self.cal.get_columbus_day(2019) self.assertEqual(label, "Indigenous People's Day") # Like California, except: # * No Chavez Day, # * Added Columbus Day class CaliforniaSanFranciscoTest(UnitedStatesTest): cal_class = CaliforniaSanFrancisco def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertNotIn(date(2014, 3, 31), holidays) # NO Cesar Chavez Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 3, 31), holidays) # NO Cesar Chavez Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday # Like California, except: # * No Chavez Day, # * No Thanksgiving Friday # * Added Harvey Milk Day class CaliforniaWestHollywoodTest(NoColumbus, UnitedStatesTest): cal_class = CaliforniaWestHollywood def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertNotIn(date(2014, 3, 31), holidays) # NO Cesar Chavez Day self.assertNotIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 3, 31), holidays) # NO Cesar Chavez Day self.assertNotIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_harvey_milk_day(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 5, 22), holidays) # Harvey Milk Day holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 5, 22), holidays) # Harvey Milk Day class ColoradoTest(UnitedStatesTest): cal_class = Colorado # Colorado has only federal state holidays. # NOTE: Cesar Chavez Day is an optional holiday class ConnecticutTest(UnitedStatesTest): cal_class = Connecticut def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2014, 4, 18), holidays) # Good Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2015, 4, 3), holidays) # Good Friday class DelawareTest(ElectionDayEvenYears, NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = Delaware def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class DistrictOfColumbiaTest(InaugurationDay, UnitedStatesTest): cal_class = DistrictOfColumbia def test_state_year_2017(self): # President elected in 2016, Inauguration Day is year+1 holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 1, 20), holidays) # Inauguration Day self.assertIn(date(2017, 4, 16), holidays) # Emancipation Day def test_state_year_2016(self): holidays = self.cal.holidays_set(2016) # No Inauguration Day the other years self.assertNotIn(date(2016, 1, 20), holidays) self.assertIn(date(2016, 4, 16), holidays) # Emancipation Day class FloridaBasicTest: """ Core Florida tests. The difference is that it includes the Thanksgiving Friday *and* its label is renamed. """ def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) observed = self.cal.observed_holidays(2015) self.assertIn(date(2015, 7, 3), observed) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Friday after Thanksgiving") class FloridaTest(NoColumbus, NoPresidentialDay, FloridaBasicTest, UnitedStatesTest): """ Florida includes all federal holidays except Washington's Birthday & Columbus day """ cal_class = Florida class FloridaLegalTest(IncludeMardiGras, ElectionDayEveryYear, FloridaBasicTest, UnitedStatesTest): """ Florida Legal Holidays include: * All Florida State Holidays, * Mardi Gras, * Lincoln's Birthday, * Susan B. Anthony Day, * Washington's Birthday, * Good Friday, * Pascua Florida Day, * Confederate Memorial Day, * Jefferson Davies Birthday, * Flag Day * Columbus Day renamed as "Columbus and Farmers' Day" * Election Day """ cal_class = FloridaLegal def test_init_warning(self): msg = ( "Florida's laws separate the definitions between " "paid versus legal holidays." ) with pytest.warns(UserWarning, match=msg): self.cal_class() def test_specific_lincoln_birthday(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday def test_susan_b_anthony_day(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 2, 15), holidays) # Susan B. Anthony Day def test_good_friday(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday def test_pascua_florida_day(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 2), holidays) # Pascua Florida Day def test_confederate_holidays(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 26), holidays) # Confederate Memorial Day self.assertIn(date(2014, 6, 3), holidays) # Jefferson Davis' birthday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 26), holidays) # Confederate Memorial Day self.assertIn(date(2015, 6, 3), holidays) # Jefferson Davis' birthday holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 4, 26), holidays) # Confederate Memorial Day self.assertIn(date(2018, 6, 3), holidays) # Jefferson Davis' birthday def test_flag_day(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 6, 14), holidays) # Flag Day holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 6, 14), holidays) # Flag Day def test_columbus_day_label(self): _, label = self.cal.get_columbus_day(2017) self.assertEqual(label, "Columbus Day and Farmers' Day") class FloridaCircuitCourtsTest(NoColumbus, FloridaBasicTest, UnitedStatesTest): cal_class = FloridaCircuitCourts def test_good_friday(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday def test_rosh_hashanah_2018(self): # src: https://www.firstjudicialcircuit.org/about-court/court-holidays rosh_hashanah = self.cal.get_rosh_hashanah(2018) self.assertEqual(rosh_hashanah, date(2018, 9, 10)) holidays = self.cal.holidays_set(2018) self.assertIn(rosh_hashanah, holidays) def test_rosh_hashanah_2019(self): # src: https://www.firstjudicialcircuit.org/about-court/court-holidays rosh_hashanah = self.cal.get_rosh_hashanah(2019) self.assertEqual(rosh_hashanah, date(2019, 9, 30)) holidays = self.cal.holidays_set(2019) self.assertIn(rosh_hashanah, holidays) def test_yom_kippur_2018(self): # src: https://www.firstjudicialcircuit.org/about-court/court-holidays yom_kippur = self.cal.get_yom_kippur(2018) self.assertEqual(yom_kippur, date(2018, 9, 19)) holidays = self.cal.holidays_set(2018) self.assertIn(yom_kippur, holidays) def test_yom_kippur_2019(self): # src: https://www.firstjudicialcircuit.org/about-court/court-holidays yom_kippur = self.cal.get_yom_kippur(2019) self.assertEqual(yom_kippur, date(2019, 10, 9)) holidays = self.cal.holidays_set(2019) self.assertIn(yom_kippur, holidays) class FloridaMiamiDadeTests(FloridaBasicTest, UnitedStatesTest): cal_class = FloridaMiamiDade class GeorgiaTest(NoPresidentialDay, UnitedStatesTest): cal_class = Georgia def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 28), holidays) # Confederate Memorial self.assertIn(date(2014, 12, 26), holidays) # Washington bday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 27), holidays) # Confederate Memorial self.assertIn(date(2015, 12, 24), holidays) # Washington bday def test_washington_birthday(self): # Sources: # * https://georgia.gov/popular-topic/observing-state-holidays # * https://georgia.gov/popular-topic/state-holidays day, _ = self.cal.get_washington_birthday_december(2020) self.assertEqual(day, date(2020, 12, 24)) day, _ = self.cal.get_washington_birthday_december(2019) self.assertEqual(day, date(2019, 12, 24)) day, _ = self.cal.get_washington_birthday_december(2018) self.assertEqual(day, date(2018, 12, 24)) day, _ = self.cal.get_washington_birthday_december(2017) self.assertEqual(day, date(2017, 12, 26)) day, _ = self.cal.get_washington_birthday_december(2016) self.assertEqual(day, date(2016, 12, 27)) day, _ = self.cal.get_washington_birthday_december(2015) self.assertEqual(day, date(2015, 12, 24)) day, _ = self.cal.get_washington_birthday_december(2014) self.assertEqual(day, date(2014, 12, 26)) day, _ = self.cal.get_washington_birthday_december(2013) self.assertEqual(day, date(2013, 12, 24)) day, _ = self.cal.get_washington_birthday_december(2012) self.assertEqual(day, date(2012, 12, 24)) # Source: # https://web.archive.org/web/20110927122533/http://www.georgia.gov/00/channel_modifieddate/0,2096,4802_64437763,00.html # noqa day, _ = self.cal.get_washington_birthday_december(2011) self.assertEqual(day, date(2011, 12, 26)) # Source: # https://web.archive.org/web/20100304032739/http://www.georgia.gov/00/channel_modifieddate/0,2096,4802_64437763,00.html # noqa day, _ = self.cal.get_washington_birthday_december(2010) self.assertEqual(day, date(2010, 12, 23)) def test_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 1, 1), holidays) # New Year self.assertIn(date(2019, 1, 21), holidays) # MLK self.assertIn(date(2019, 4, 22), holidays) # state holiday self.assertIn(date(2019, 5, 27), holidays) # memorial day self.assertIn(date(2019, 7, 4), holidays) # Independance day self.assertIn(date(2019, 9, 2), holidays) # Labor day self.assertIn(date(2019, 10, 14), holidays) # Columbus self.assertIn(date(2019, 11, 11), holidays) # Veterans self.assertIn(date(2019, 11, 28), holidays) # Thanksgiving self.assertIn(date(2019, 11, 29), holidays) # State Holiday # Washington's Birthday switched to XMAS eve self.assertIn(date(2019, 12, 24), holidays) self.assertIn(date(2019, 12, 25), holidays) # XMAS def test_year_2020(self): holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 1, 1), holidays) # New Year self.assertIn(date(2020, 1, 20), holidays) # MLK # State holiday special case # Confederate memorial day has been shifted to April 10th. # Reason is unknown, so we're adding a single exception in the # `get_confederate_day` self.assertNotIn(date(2020, 4, 26), holidays) self.assertIn(date(2020, 4, 10), holidays) self.assertIn(date(2020, 5, 25), holidays) # memorial day observed = self.cal.observed_holidays(2020) # Independance day (OBS) self.assertIn(date(2020, 7, 3), observed) self.assertIn(date(2020, 7, 4), holidays) # Independance day self.assertIn(date(2020, 9, 7), holidays) # Labor day self.assertIn(date(2020, 10, 12), holidays) # Columbus self.assertIn(date(2020, 11, 11), holidays) # Veterans self.assertIn(date(2020, 11, 26), holidays) # Thanksgiving self.assertIn(date(2020, 11, 27), holidays) # State Holiday self.assertIn(date(2020, 12, 24), holidays) # Washington B'day self.assertIn(date(2020, 12, 25), holidays) # XMAS def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label # Until 2016, the 4th FRI of november was labelled # "Robert E. Lee's Birthday (Observed)" for year in (2013, 2014, 2015,): _, label = self.cal.get_robert_lee_birthday(year) self.assertEqual(label, "Robert E. Lee's Birthday (Observed)") for year in (2016, 2017, 2018, 2019, 2020): _, label = self.cal.get_robert_lee_birthday(year) self.assertEqual(label, "State Holiday") def test_get_confederate_day_label(self): # Until 2016, it was labelled "Confederate Memorial Day" for year in (2013, 2014, 2015,): _, label = self.cal.get_confederate_day(year) self.assertEqual(label, "Confederate Memorial Day") for year in (2016, 2017, 2018, 2019, 2020): _, label = self.cal.get_confederate_day(year) self.assertEqual(label, "State Holiday") class HawaiiTest(ElectionDayEvenYears, NoColumbus, UnitedStatesTest): cal_class = Hawaii def test_state_year_2017(self): holidays = self.cal.holidays_set(2017) observed = self.cal.observed_holidays(2017) self.assertIn(date(2017, 3, 26), holidays) # Prince Jonah Kuhio Kalanianaole self.assertIn(date(2017, 3, 27), observed) # Prince Jonah Kuhio Kalanianaole (shifted) self.assertIn(date(2017, 4, 14), holidays) # Good Friday self.assertIn(date(2017, 6, 11), holidays) # Kamehameha self.assertIn(date(2017, 6, 12), observed) # Kamehameha (shifted) self.assertIn(date(2017, 8, 18), holidays) # Statehood day def test_state_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 3, 26), holidays) # Prince Jonah Kuhio Kalanianaole self.assertIn(date(2018, 3, 30), holidays) # Good Friday self.assertIn(date(2018, 6, 11), holidays) # Kamehameha self.assertIn(date(2018, 8, 17), holidays) # Statehood day # Prince Jonah Kuhio Kalanianaole is not shifted self.assertNotIn(date(2018, 3, 27), holidays) # Kamehameha is not shifted self.assertNotIn(date(2018, 6, 12), holidays) class IdahoTest(UnitedStatesTest): cal_class = Idaho # NOTE: Idaho only has federal holidays. def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label # Martin Luther King day is renamed in Idaho _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual( label, "Martin Luther King Jr. / Idaho Human Rights Day") class IllinoisTest(ElectionDayEvenYears, UnitedStatesTest): cal_class = Illinois def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class ChicagoIllinoisTest(ElectionDayEvenYears, UnitedStatesTest): cal_class = ChicagoIllinois def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday # Thanksgiving Friday is NOT a holiday in Chicago. self.assertNotIn(date(2014, 11, 28), holidays) def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday # Thanksgiving Friday is NOT a holiday in Chicago. self.assertNotIn(date(2015, 11, 27), holidays) def test_pulaski_day(self): # Pulaski day is on the first MON in March. # Source: https://en.wikipedia.org/wiki/Casimir_Pulaski_Day holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 3, 5), holidays) holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 4), holidays) holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 3, 2), holidays) holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 3, 1), holidays) class IndianaTest(ElectionDayEvenYears, NoPresidentialDay, UnitedStatesTest): cal_class = Indiana def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday # Thanksgiving Friday -- Renamed into Lincoln's Birthday self.assertIn(date(2014, 11, 28), holidays) # FIXME: this holiday rule is Confusing, probably false self.assertIn(date(2014, 12, 26), holidays) # Washington bday # Primary Election Day, only happen on even years self.assertIn(date(2014, 5, 6), holidays) def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday # Thanksgiving Friday -- Renamed into Lincoln's Birthday self.assertIn(date(2015, 11, 27), holidays) # FIXME: this holiday rule is Confusing, probably false self.assertIn(date(2015, 12, 24), holidays) # Washington bday # Primary Election Day, only happen on even years self.assertNotIn(date(2015, 5, 5), holidays) def test_primary_election_day(self): # Source: # -> https://www.timeanddate.com/holidays/us/primary-election-indiana # Year 2010 election_day, _ = self.cal.get_primary_election_day(2010) self.assertEqual(election_day, date(2010, 5, 4)) # Year 2012 election_day, _ = self.cal.get_primary_election_day(2012) self.assertEqual(election_day, date(2012, 5, 8)) # Year 2014 election_day, _ = self.cal.get_primary_election_day(2014) self.assertEqual(election_day, date(2014, 5, 6)) # Year 2016 election_day, _ = self.cal.get_primary_election_day(2016) self.assertEqual(election_day, date(2016, 5, 3)) def test_election_day_label(self): # Overwrite UnitedStatesTest.test_election_day_label # Election Day is "General Election Day" in Indiana _, label = self.cal.get_election_day(2017) self.assertEqual(label, "General Election Day") def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label # Lincoln's Birthday is set on Thanksgiving Friday _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Lincoln's Birthday") @skip("Confusing Rule, it's impossible to decide") def test_washington_birthday(self): # Sources: # http://www.in.gov/spd/files/2018_Holidays.pdf # http://www.in.gov/spd/files/2017_Holidays.pdf # http://www.in.gov/spd/files/2016_Holidays.pdf # Year 2016, shifted to the 26th washington_bday = self.cal.get_washington_birthday_december(2016) self.assertEqual(date(2016, 12, 26), washington_bday) # Year 2017, shifted to the 26th washington_bday = self.cal.get_washington_birthday_december(2017) self.assertEqual(date(2017, 12, 26), washington_bday) # Year 2018, back to XMas Eve washington_bday = self.cal.get_washington_birthday_december(2018) self.assertEqual(date(2018, 12, 24), washington_bday) class IowaTest(NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = Iowa def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) observed = self.cal.observed_holidays(2015) self.assertIn(date(2015, 7, 3), observed) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class KansasTest(NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = Kansas class KentuckyTest(NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = Kentucky def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve self.assertIn(date(2014, 12, 31), holidays) # NY Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 24), holidays) # XMas Eve self.assertIn(date(2015, 12, 31), holidays) # NY Eve class LouisianaTest(IncludeMardiGras, NoColumbus, ElectionDayEvenYears, UnitedStatesTest): cal_class = Louisiana def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday class MaineTest(UnitedStatesTest): cal_class = Maine def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 21), holidays) # Patriot's day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 20), holidays) # Patriot's day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class MarylandTest(ElectionDayPresidentialYears, UnitedStatesTest): cal_class = Maryland def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) # Thanksgiving Friday == Native American Heritage Day self.assertIn(date(2014, 11, 28), holidays) def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) # Thanksgiving Friday == Native American Heritage Day self.assertIn(date(2015, 11, 27), holidays) def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label # Thanksgiving Friday label changed to "Native American Heritage Day" _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Native American Heritage Day") class MassachusettsTest(UnitedStatesTest): cal_class = Massachusetts def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 21), holidays) # Patriot's day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 20), holidays) # Patriot's day class SuffolkCountyMassachusettsTest(MassachusettsTest): cal_class = SuffolkCountyMassachusetts def test_county_year_2018(self): holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 3, 17), holidays) # Evacuation Day self.assertIn(date(2018, 6, 17), holidays) # Bunker Hill Day def test_county_year_2019(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 3, 17), holidays) # Evacuation Day self.assertIn(date(2019, 6, 17), holidays) # Bunker Hill Day class MichiganTest(NoColumbus, ElectionDayEvenYears, UnitedStatesTest): cal_class = Michigan def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve self.assertIn(date(2014, 12, 31), holidays) # New Years Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 24), holidays) # XMas Eve self.assertIn(date(2015, 12, 31), holidays) # New Years Eve def test_state_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 11, 24), holidays) # Thanksgiving Friday # XMas Eve self.assertIn(date(2017, 12, 24), holidays) # XMAs Eve is on SUN, shifted to Dec, 22nd self.assertIn(date(2017, 12, 22), holidays) # New Years Eve self.assertIn(date(2017, 12, 31), holidays) # New Years Eve is on SUN, shifted to Dec, 29nd self.assertIn(date(2017, 12, 29), holidays) class MinnesotaTest(NoColumbus, UnitedStatesTest): cal_class = Minnesota def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class MississippiTest(NoColumbus, UnitedStatesTest): cal_class = Mississippi def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 28), holidays) # Confederate Memorial Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 27), holidays) # Confederate Memorial Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label # Martin Luther King day is renamed in Mississippi _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual( label, "Martin Luther King's and Robert E. Lee's Birthdays") def test_national_memorial_label(self): # Overwrite UnitedStatesTest.test_national_memorial_label # National Memorial Day is renamed in Mississippi _, label = self.cal.get_national_memorial_day(2017) self.assertEqual( label, "National Memorial Day / Jefferson Davis Birthday") def test_veterans_label(self): # Overwrite UnitedStatesTest.test_veterans_label # Veterans Day is renamed in Mississippi _, label = self.cal.get_veterans_day(2017) self.assertEqual(label, "Armistice Day (Veterans Day)") class MissouriTest(UnitedStatesTest): cal_class = Missouri def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2014, 5, 8), holidays) # Truman Day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday self.assertIn(date(2015, 5, 8), holidays) # Truman Day class MontanaTest(ElectionDayEvenYears, UnitedStatesTest): cal_class = Montana # NOTE: Montana include only Federal Holidays + General Election Day class NebraskaTest(UnitedStatesTest): cal_class = Nebraska def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 25), holidays) # Arbor Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 24), holidays) # Arbor Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class NevadaTest(NoColumbus, UnitedStatesTest): cal_class = Nevada def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 10, 31), holidays) # Nevada Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 10, 30), holidays) # Nevada Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label # Thanksgiving Friday Label is Family Day in Nevada _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Family Day") class NewHampshireTest(UnitedStatesTest): cal_class = NewHampshire def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label # Martin Luther King day is renamed in New Hampshire _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual(label, "Martin Luther King, Jr. Civil Rights Day") class NewJerseyTest(ElectionDayEveryYear, UnitedStatesTest): cal_class = NewJersey def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday class NewMexicoTest(NoPresidentialDay, UnitedStatesTest): cal_class = NewMexico def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_thanksgiving_friday_label(self): # Overwrite UnitedStatesTest.test_thanksgiving_friday_label # New Mexico is celebrating Presidents' Day on Thanksgiving Friday _, label = self.cal.get_thanksgiving_friday(2017) self.assertEqual(label, "Presidents' Day") class NewYorkTest(ElectionDayEveryYear, UnitedStatesTest): cal_class = NewYork def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 2, 12), holidays) # Lincoln's Birthday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 2, 12), holidays) # Lincoln's Birthday class NorthCarolinaTest(NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = NorthCarolina def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday self.assertIn(date(2014, 11, 27), holidays) # Thanksgiving Thursday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve self.assertIn(date(2014, 12, 26), holidays) # Boxing Day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 11, 26), holidays) # Thanksgiving Thursday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 24), holidays) # Xmas Eve self.assertIn(date(2015, 12, 26), holidays) # Boxing Day def test_federal_year_2017(self): # It is different from other federal days. holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 4, 14), holidays) # Good Friday self.assertIn(date(2017, 11, 23), holidays) # Thanksgiving Thursday self.assertIn(date(2017, 11, 24), holidays) # Thanksgiving Friday self.assertIn(date(2017, 12, 24), holidays) # Xmas Eve self.assertIn(date(2017, 12, 25), holidays) # Xmas Day self.assertIn(date(2017, 12, 26), holidays) # Day after Xmas self.assertIn(date(2017, 12, 27), holidays) # Xmas Shift def test_state_year_2016_xmas(self): # XMAS falls on SUN holidays = self.cal.holidays_set(2016) self.assertIn(date(2016, 12, 23), holidays) # Day 1 - FRI self.assertIn(date(2016, 12, 26), holidays) # Day 2 - MON self.assertIn(date(2016, 12, 27), holidays) # Day 3 - TUE # 22nd and 28th are not included self.assertNotIn(date(2016, 12, 22), holidays) # THU self.assertNotIn(date(2016, 12, 28), holidays) # WED def test_state_year_2017_xmas(self): # XMAS falls on MON holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 12, 25), holidays) # Day 1 - MON self.assertIn(date(2017, 12, 26), holidays) # Day 2 - TUE self.assertIn(date(2017, 12, 27), holidays) # Day 3 - WED # 22nd and 28th are not included self.assertNotIn(date(2017, 12, 22), holidays) # FRI self.assertNotIn(date(2017, 12, 23), holidays) # SAT self.assertNotIn(date(2017, 12, 28), holidays) # THU def test_state_year_2018_xmas(self): # XMAS falls on TUE holidays = self.cal.holidays_set(2018) self.assertIn(date(2018, 12, 24), holidays) # Day 1 - MON self.assertIn(date(2018, 12, 25), holidays) # Day 2 - TUE self.assertIn(date(2018, 12, 26), holidays) # Day 3 - WED # No shift: self.assertNotIn(date(2018, 12, 23), holidays) self.assertNotIn(date(2018, 12, 27), holidays) def test_state_year_2019_xmas(self): # XMAS falls on WED holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 12, 24), holidays) # Day 1 - TUE self.assertIn(date(2019, 12, 25), holidays) # Day 2 - WED self.assertIn(date(2019, 12, 26), holidays) # Day 3 - THU # No shift: self.assertNotIn(date(2019, 12, 23), holidays) self.assertNotIn(date(2019, 12, 27), holidays) def test_state_year_2020_xmas(self): # XMAS falls on FRI holidays = self.cal.holidays_set(2020) self.assertIn(date(2020, 12, 24), holidays) # Day 1 - THU self.assertIn(date(2020, 12, 25), holidays) # Day 2 - FRI self.assertIn(date(2020, 12, 28), holidays) # Day 3 - MON # 23rd and 29th are not included self.assertNotIn(date(2020, 12, 23), holidays) self.assertNotIn(date(2020, 12, 29), holidays) def test_state_year_2021_xmas(self): # XMAS falls on SAT holidays = self.cal.holidays_set(2021) self.assertIn(date(2021, 12, 23), holidays) # Day 1 - THU self.assertIn(date(2021, 12, 24), holidays) # Day 2 - FRI self.assertIn(date(2021, 12, 27), holidays) # Day 3 - MON # 23rd and 29th are not included self.assertNotIn(date(2021, 12, 22), holidays) self.assertNotIn(date(2021, 12, 28), holidays) class NorthDakotaTest(NoColumbus, UnitedStatesTest): cal_class = NorthDakota def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday class OhioTest(UnitedStatesTest): cal_class = Ohio # Ohio includes only Federal holidays. # The wikipedia page say it also includes Election Day, but no official # document confirms this. class OklahomaTest(NoColumbus, UnitedStatesTest): cal_class = Oklahoma def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 26), holidays) # Boxing day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 26), holidays) # Boxing day class OregonTest(NoColumbus, UnitedStatesTest): cal_class = Oregon # NOTE: Oregon has only the federal holidays, except Columbus Day class PennsylvaniaTest(ElectionDayEveryYear, UnitedStatesTest): cal_class = Pennsylvania def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday class RhodeIslandTest(NoPresidentialDay, ElectionDayEvenYears, UnitedStatesTest): cal_class = RhodeIsland def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 8, 11), holidays) # Victory Day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 8, 10), holidays) # Victory Day class SouthCarolinaTest(NoColumbus, UnitedStatesTest): cal_class = SouthCarolina def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) observed = self.cal.observed_holidays(2014) # Confederate Memorial Day self.assertIn(date(2014, 5, 10), holidays) # Observed here, it falls on SAT self.assertIn(date(2014, 5, 9), observed) self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), observed) # XMas Eve self.assertIn(date(2014, 12, 26), observed) # Boxing day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 5, 10), holidays) # Confederate Memorial Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 24), holidays) # Xmas Eve self.assertIn(date(2015, 12, 26), holidays) # Boxing day @skip("No clear rules for implementing the XMas Eve shift") def test_state_year_2017(self): holidays = self.cal.holidays_set(2017) self.assertIn(date(2017, 5, 10), holidays) # Confederate Memorial Day self.assertIn(date(2017, 11, 23), holidays) # Thanksgiving Friday # Xmas Eve falls on SUN self.assertIn(date(2017, 12, 24), holidays) # Christmas Eve observed here self.assertIn(date(2017, 12, 22), holidays) self.assertIn(date(2017, 12, 26), holidays) # Boxing day class SouthDakotaTest(UnitedStatesTest): cal_class = SouthDakota # NOTE: South Dakota has all federal holidays, except Columbus Day, # but it's renamed as "Native Americans Day" def test_columbus_day_label(self): # Overwrite UnitedStatesTest.test_columbus_day_label _, label = self.cal.get_columbus_day(2017) self.assertEqual(label, "Native Americans Day") class TennesseeTest(NoColumbus, UnitedStatesTest): cal_class = Tennessee def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 4, 18), holidays) # Good Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 4, 3), holidays) # Good Friday self.assertIn(date(2015, 12, 24), holidays) # XMas Eve class TexasBaseTest(NoColumbus, UnitedStatesTest): cal_class = TexasBase # NOTE: "Stock" Texas doesn't include Columbus Day, # state holidays are handled differently def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) # Check that state holidays are not included here self.assertNotIn(date(2014, 1, 19), holidays) # Confederate Heroes Day self.assertNotIn(date(2014, 3, 2), holidays) # Texas Independence Day self.assertNotIn(date(2014, 4, 21), holidays) # San Jacinto Day self.assertNotIn(date(2014, 6, 19), holidays) # Emancipation Day self.assertNotIn(date(2014, 8, 27), holidays) # Lyndon B. Johnson Day self.assertNotIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertNotIn(date(2014, 12, 24), holidays) # XMas Eve self.assertNotIn(date(2014, 12, 26), holidays) # Boxing day class TexasTest(TexasBaseTest): cal_class = Texas def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 19), holidays) # Confederate Heroes Day self.assertIn(date(2014, 3, 2), holidays) # Texas Independence Day self.assertIn(date(2014, 4, 21), holidays) # San Jacinto Day self.assertIn(date(2014, 6, 19), holidays) # Emancipation Day self.assertIn(date(2014, 8, 27), holidays) # Lyndon B. Johnson Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve self.assertIn(date(2014, 12, 26), holidays) # Boxing day class UtahTest(UnitedStatesTest): cal_class = Utah def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 7, 24), holidays) # Pioneer Day def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 7, 24), holidays) # Pioneer Day class VermontTest(NoColumbus, UnitedStatesTest): cal_class = Vermont def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) observed = self.cal.observed_holidays(2014) self.assertIn(date(2014, 3, 4), holidays) # Town Meeting Day self.assertIn(date(2014, 8, 16), holidays) # Bennington Battle Day self.assertIn(date(2014, 8, 15), observed) # Shifted to FRI def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) observed = self.cal.observed_holidays(2015) self.assertIn(date(2015, 3, 3), holidays) # Town Meeting Day self.assertIn(date(2015, 8, 16), holidays) # Bennington Battle Day self.assertIn(date(2015, 8, 17), observed) # Shifted to MON class VirginiaTest(UnitedStatesTest): cal_class = Virginia def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 1, 17), holidays) # Lee-Jackson Day self.assertIn(date(2014, 11, 26), holidays) # Thanksgiving Wednesday self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday self.assertIn(date(2014, 12, 24), holidays) # XMas Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 1, 16), holidays) # Lee-Jackson Day self.assertIn(date(2015, 11, 25), holidays) # Thanksgiving Wednesday self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday self.assertIn(date(2015, 12, 24), holidays) # XMas Eve def test_exclude_thanksgiving_wednesday(self): # Sub class class VirginiaExclude(Virginia): include_thanksgiving_wednesday = False cal = VirginiaExclude() holidays = cal.holidays_set(2015) # Not Thanksgiving Wednesday self.assertNotIn(date(2015, 11, 25), holidays) def test_president_day_label(self): # Overwrite UnitedStatesTest.test_president_day_label _, label = self.cal.get_presidents_day(2017) self.assertEqual(label, "George Washington Day") def test_inauguration_day(self): # Overwriting this test: in 2017, this day is a public holiday for # Virginia State: Lee-Jackson Day # NOTE: 2013 test is not relevant, it's the same day as MLK day. # NOTE: 1985 test is not relevant, it's the same day as MLK day. # By default, it's not a public holiday self.assertNotIn( self.cal.get_inauguration_date(2009), self.cal.holidays_set(2009) ) self.assertNotIn( self.cal.get_inauguration_date(1957), self.cal.holidays_set(1957) ) class WashingtonTest(NoColumbus, UnitedStatesTest): cal_class = Washington # NOTE: Washington State includes all federal holidays, except Columbus Day class WestVirginiaTest(ElectionDayEvenYears, UnitedStatesTest): cal_class = WestVirginia def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 6, 20), holidays) # West Virginia Day self.assertIn(date(2014, 11, 28), holidays) # Thanksgiving Friday def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 6, 20), holidays) # West Virginia Day self.assertIn(date(2015, 11, 27), holidays) # Thanksgiving Friday def test_state_half_holidays_base(self): # Using the "stock" calendar holidays = self.cal.holidays_set(2015) self.assertNotIn(date(2015, 12, 24), holidays) # XMas Eve self.assertNotIn(date(2015, 12, 31), holidays) # NYE def test_state_half_holidays_included(self): class WestVirginiaInclude(WestVirginia): west_virginia_include_christmas_eve = True west_virginia_include_nye = True cal = WestVirginiaInclude() holidays = cal.holidays_set(2015) self.assertIn(date(2015, 12, 24), holidays) # XMas Eve self.assertIn(date(2015, 12, 31), holidays) # NYE # Test that these days are not shifted # In 2016, XMas Eve and NYE are on SAT holidays = cal.holidays_set(2016) self.assertIn(date(2016, 12, 24), holidays) # XMas Eve self.assertIn(date(2016, 12, 31), holidays) # NYE self.assertNotIn(date(2016, 12, 23), holidays) # NO SHIFT for XMas Eve self.assertNotIn(date(2016, 12, 30), holidays) # NO SHIFT for NYE def test_election_day_label(self): # Overwrite UnitedStatesTest.test_election_day_label _, label = self.cal.get_election_day(2017) self.assertEqual(label, "Election Day / Susan B. Anthony Day") class WisconsinTest(NoPresidentialDay, NoColumbus, UnitedStatesTest): cal_class = Wisconsin def test_state_year_2014(self): holidays = self.cal.holidays_set(2014) self.assertIn(date(2014, 12, 24), holidays) # Xmas Eve self.assertIn(date(2014, 12, 31), holidays) # New Years Eve def test_state_year_2015(self): holidays = self.cal.holidays_set(2015) self.assertIn(date(2015, 12, 24), holidays) # Xmas Eve self.assertIn(date(2015, 12, 31), holidays) # New Years Eve class WyomingTest(UnitedStatesTest): cal_class = Wyoming # NOTE: Wyoming only has all federal holidays def test_mlk_label(self): # Overwrite UnitedStatesTest.test_mlk_label _, label = self.cal.get_martin_luther_king_day(2017) self.assertEqual( label, "Martin Luther King, Jr. / Wyoming Equality Day" ) class AmericanSamoaTest(UnitedStatesTest): cal_class = AmericanSamoa def test_family_day(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 12, 26), holidays) # Family Day def test_flag_day(self): holidays = self.cal.holidays_set(2019) self.assertIn(date(2019, 4, 17), holidays) # Flag Day def test_family_day_label(self): holidays = self.cal.holidays(2019) holidays_dict = dict(holidays) self.assertEqual(holidays_dict[date(2019, 12, 26)], "Family Day") class Guam(UnitedStatesTest): cal_class = Guam def test_state_year_2019(self): holidays = self.cal.holidays_set(2019) # Guam History and Chamorro Heritage Day self.assertIn(date(2019, 3, 7), holidays) self.assertIn(date(2019, 7, 21), holidays) # Liberation Day self.assertIn(date(2019, 11, 2), holidays) # All Souls Day self.assertIn(date(2019, 12, 8), holidays) # Lady of Camarin Day def test_state_year_2018(self): holidays = self.cal.holidays_set(2020) # Guam History and Chamorro Heritage Day self.assertIn(date(2020, 3, 7), holidays) self.assertIn(date(2020, 7, 21), holidays) # Liberation Day self.assertIn(date(2020, 11, 2), holidays) # All Souls Day self.assertIn(date(2020, 12, 8), holidays) # Lady of Camarin Day def test_lady_of_camarin_label(self): holidays = self.cal.holidays(2019) holidays_dict = dict(holidays) self.assertEqual( holidays_dict[date(2019, 12, 8)], "Lady of Camarin Day" ) class NormalShiftTestCase(UnitedStatesTest): # Using a fake calendar here class NormalShiftUnitedStates(UnitedStates): "Normal Shift Fake United State calendar" include_christmas_eve = True cal_class = NormalShiftUnitedStates def test_shift_2015(self): # Test a normal shift on 4th of July. # 2015: Happens on a Saturday, observed on FRI holidays = self.cal.holidays(2015) holiday_dict = dict(holidays) fourth_july = date(2015, 7, 4) observed = date(2015, 7, 3) self.assertIn(fourth_july, holiday_dict) self.assertEqual(holiday_dict[fourth_july], "Independence Day") self.assertNotIn(observed, holiday_dict) def test_shift_2010(self): # Test a normal shift on 4th of July. # 2010: Happens on a SUN, observed on MON holidays = self.cal.holidays(2010) holiday_dict = dict(holidays) fourth_july = date(2010, 7, 4) observed = date(2010, 7, 5) self.assertIn(fourth_july, holiday_dict) self.assertEqual(holiday_dict[fourth_july], "Independence Day") self.assertNotIn(observed, holiday_dict) def test_new_years_shift(self): # If January, 1st *of the year after* happens on SAT, add New Years Eve holidays = self.cal.holidays(2010) holiday_dict = dict(holidays) new_years_eve = date(2010, 12, 31) self.assertNotIn(new_years_eve, holiday_dict) # The year after, it's not shifted holidays = self.cal.holidays_set(2011) new_years_eve = date(2011, 12, 31) self.assertNotIn(new_years_eve, holidays) def test_christmas_extra_shift_2010(self): # XMAs Eve is included. *and* XMas falls on SAT. # So you have the following holidays: # * 24th & 25th (XMas Eve and XMas day) # * 27th (XMas Shift) # * 23rd (XMas Eve shifted on THU) holidays = self.cal.holidays(2010) holiday_dict = dict(holidays) dec_24th = date(2010, 12, 24) dec_25th = date(2010, 12, 25) for day in (dec_24th, dec_25th): self.assertIn(day, holiday_dict) self.assertEqual(holiday_dict[dec_24th], "Christmas Eve") self.assertEqual(holiday_dict[dec_25th], "Christmas Day") def test_christmas_extra_shift_2006(self): # XMAs Eve is included. *and* XMas falls on MON. # So you have the following holidays: # * 24th & 25th (XMas Eve and XMas day) # * 26th (XMas Shift) holidays = self.cal.holidays(2006) holiday_dict = dict(holidays) dec_24th = date(2006, 12, 24) dec_25th = date(2006, 12, 25) for day in (dec_24th, dec_25th): self.assertIn(day, holiday_dict) self.assertEqual(holiday_dict[dec_24th], "Christmas Eve") self.assertEqual(holiday_dict[dec_25th], "Christmas Day") class ShiftExceptionsTestCase(UnitedStatesTest): # Using a fake calendar here class ShiftExceptionsCalendar(UnitedStates): "Normal Shift Fake United State calendar" shift_exceptions = ( (7, 4), # Month/Day == Fourth of July. ) cal_class = ShiftExceptionsCalendar def test_shift_2015(self): # Test a normal shift on 4th of July. # 2015: Happens on a Saturday, not shifted holidays = self.cal.holidays(2015) holiday_dict = dict(holidays) fourth_july = date(2015, 7, 4) observed = date(2015, 7, 3) self.assertIn(fourth_july, holiday_dict) self.assertEqual(holiday_dict[fourth_july], "Independence Day") self.assertNotIn(observed, holiday_dict) def test_shift_2010(self): # Test a normal shift on 4th of July. # 2010: Happens on a SUN, not shifted holidays = self.cal.holidays(2010) holiday_dict = dict(holidays) fourth_july = date(2010, 7, 4) observed = date(2010, 7, 5) self.assertIn(fourth_july, holiday_dict) self.assertEqual(holiday_dict[fourth_july], "Independence Day") self.assertNotIn(observed, holiday_dict) class ShiftExceptionsNextYearTestCase(UnitedStatesTest): class ShiftExceptionsCalendar(UnitedStates): "Shift exception happens on jan 1st and XMas" shift_exceptions = ( (1, 1), # January 1st (12, 25), # Christmas Day ) cal_class = ShiftExceptionsCalendar def test_shift_2021(self): # January 1st is a saturday in 2022 # As a consequence, Dec 31st should be a holiday. # BUT here, January 1st is in the shift_exceptions, # so 2021-12-31 should be a working day holidays = self.cal.holidays_set(2021) # XMas is a holiday self.assertIn(date(2021, 12, 25), holidays) # XMas eve is a working day self.assertNotIn(date(2021, 12, 24), holidays) # January 1st is a non-shift, Dec 31st should be a working day self.assertNotIn(date(2021, 12, 31), holidays) self.assertTrue(self.cal.is_working_day(date(2021, 12, 31))) class FederalReserveSystemTest(UnitedStatesTest): cal_class = FederalReserveSystem def test_juneteenth_day(self): holidays = self.cal.holidays_set(2021) observed = self.cal.observed_holidays(2021) juneteenth, _ = self.cal.get_juneteenth_day(2021) self.assertEqual(date(2021, 6, 19), juneteenth) # 2021-06-19 is a Saturday so holiday is shifted self.assertIn(date(2021, 6, 18), observed) holidays = self.cal.holidays_set(2022) observed = self.cal.observed_holidays(2022) juneteenth, _ = self.cal.get_juneteenth_day(2022) self.assertEqual(date(2022, 6, 19), juneteenth) # 2022-06-19 is a Sunday so holiday is shifted self.assertIn(date(2022, 6, 20), observed) holidays = self.cal.holidays_set(2023) juneteenth, _ = self.cal.get_juneteenth_day(2023) self.assertEqual(date(2023, 6, 19), juneteenth) self.assertIn(juneteenth, holidays) # No JuneTeeth before 2021 holidays = self.cal.holidays_set(2020) self.assertNotIn(date(2020, 6, 20), holidays) with self.assertRaises(ValueError): self.cal.get_juneteenth_day(2020) calendra-7.9.0/calendra/usa/000077500000000000000000000000001457013633400156475ustar00rootroot00000000000000calendra-7.9.0/calendra/usa/__init__.py000066400000000000000000000064561457013633400177730ustar00rootroot00000000000000from .core import UnitedStates, FederalReserveSystem from .alabama import ( Alabama, AlabamaBaldwinCounty, AlabamaMobileCounty, AlabamaPerryCounty) from .alaska import Alaska from .arizona import Arizona from .arkansas import Arkansas from .california import ( California, CaliforniaEducation, CaliforniaBerkeley, CaliforniaSanFrancisco, CaliforniaWestHollywood, ) from .colorado import Colorado from .connecticut import Connecticut from .delaware import Delaware from .district_columbia import DistrictOfColumbia from .florida import ( Florida, FloridaLegal, FloridaCircuitCourts, FloridaMiamiDade ) from .georgia import Georgia from .hawaii import Hawaii from .idaho import Idaho from .illinois import Illinois, ChicagoIllinois from .indiana import Indiana from .iowa import Iowa from .kansas import Kansas from .kentucky import Kentucky from .louisiana import Louisiana from .maine import Maine from .maryland import Maryland from .massachusetts import Massachusetts, SuffolkCountyMassachusetts from .michigan import Michigan from .minnesota import Minnesota from .mississippi import Mississippi from .missouri import Missouri from .montana import Montana from .nebraska import Nebraska from .nevada import Nevada from .new_hampshire import NewHampshire from .new_jersey import NewJersey from .new_mexico import NewMexico from .new_york import NewYork from .north_carolina import NorthCarolina from .north_dakota import NorthDakota from .ohio import Ohio from .oklahoma import Oklahoma from .oregon import Oregon from .pennsylvania import Pennsylvania from .rhode_island import RhodeIsland from .south_carolina import SouthCarolina from .south_dakota import SouthDakota from .tennessee import Tennessee from .texas import TexasBase, Texas from .utah import Utah from .vermont import Vermont from .virginia import Virginia from .washington import Washington from .west_virginia import WestVirginia from .wisconsin import Wisconsin from .wyoming import Wyoming # Non-states territories and areas from .american_samoa import AmericanSamoa from .guam import Guam __all__ = [ 'UnitedStates', # Generic federal calendar 'Alabama', 'AlabamaBaldwinCounty', 'AlabamaMobileCounty', 'AlabamaPerryCounty', 'Alaska', 'Arizona', 'Arkansas', 'California', 'CaliforniaEducation', 'CaliforniaBerkeley', 'CaliforniaSanFrancisco', 'CaliforniaWestHollywood', 'Colorado', 'Connecticut', 'Delaware', 'DistrictOfColumbia', 'Florida', 'FloridaLegal', 'FloridaCircuitCourts', 'FloridaMiamiDade', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'ChicagoIllinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'SuffolkCountyMassachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'NewHampshire', 'NewJersey', 'NewMexico', 'NewYork', 'NorthCarolina', 'NorthDakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'RhodeIsland', 'SouthCarolina', 'SouthDakota', 'Tennessee', 'TexasBase', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'WestVirginia', 'Wisconsin', 'Wyoming', # Non-State territories 'AmericanSamoa', 'Guam', 'FederalReserveSystem' ] calendra-7.9.0/calendra/usa/alabama.py000066400000000000000000000022011457013633400175720ustar00rootroot00000000000000from .core import UnitedStates from ..core import MON from ..registry_tools import iso_register @iso_register('US-AL') class Alabama(UnitedStates): "Alabama" include_confederation_day = True martin_luther_king_label = "Robert E. Lee/Martin Luther King Birthday" presidents_day_label = "George Washington/Thomas Jefferson Birthday" columbus_day_label = ("Columbus Day / Fraternal Day /" " American Indian Heritage Day") include_jefferson_davis_birthday = True class AlabamaBaldwinCounty(Alabama): "Baldwin County, Alabama" include_fat_tuesday = True class AlabamaMobileCounty(Alabama): "Mobile County, Alabama" include_fat_tuesday = True class AlabamaPerryCounty(Alabama): "Mobile Perry, Alabama" def get_obama_day(self, year): """ Obama Day happens on the 2nd MON of November. """ return ( self.get_nth_weekday_in_month(year, 11, MON, 2), "Obama Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_obama_day(year)) return days calendra-7.9.0/calendra/usa/alaska.py000066400000000000000000000011441457013633400174550ustar00rootroot00000000000000import datetime from .core import UnitedStates from ..core import MON from ..core import Holiday from ..registry_tools import iso_register @iso_register('US-AK') class Alaska(UnitedStates): """Alaska""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( Holiday( datetime.date(2000, 10, 18), 'Alaska Day', ), ) include_columbus_day = False def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (Alaska.get_last_weekday_in_month(year, 3, MON), "Seward's Day") ) return days calendra-7.9.0/calendra/usa/american_samoa.py000066400000000000000000000011261457013633400211600ustar00rootroot00000000000000from datetime import date from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-AS') class AmericanSamoa(UnitedStates): "American Samoa" include_boxing_day = True boxing_day_label = "Family Day" def get_flag_day(self, year): """ Flag day is on April 17th """ return ( date(year, 4, 17), "Flag Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ self.get_flag_day(year), ]) return days calendra-7.9.0/calendra/usa/arizona.py000066400000000000000000000004361457013633400176670ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-AZ') class Arizona(UnitedStates): """Arizona""" martin_luther_king_label = "Dr. Martin Luther King Jr./Civil Rights Day" presidents_day_label = "Lincoln/Washington Presidents' Day" calendra-7.9.0/calendra/usa/arkansas.py000066400000000000000000000005131457013633400200230ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-AR') class Arkansas(UnitedStates): """Arkansas""" include_christmas_eve = True presidents_day_label = ("George Washington's Birthday" " and Daisy Gatson Bates Day") include_columbus_day = False calendra-7.9.0/calendra/usa/california.py000066400000000000000000000041021457013633400203250ustar00rootroot00000000000000from datetime import date from .core import UnitedStates from ..core import MON, SUN from ..registry_tools import iso_register @iso_register('US-CA') class California(UnitedStates): """California""" include_thanksgiving_friday = True include_cesar_chavez_day = True include_columbus_day = False shift_exceptions = [ (3, 31) # Cesar Chavez Day should not be shifted the usual way. ] def get_cesar_chavez_days(self, year): """ Special shift rules for Cesar Chavez Day in California """ days = super().get_cesar_chavez_days(year) if date(year, 3, 31).weekday() == SUN: days.append((date(year, 4, 1), "Cesar Chavez Day (Observed)")) return days class CaliforniaEducation(California): """California Education This administration holds its own calendar. In order to respect the goal of workalendar (to compute (non)working days), we've decided to only retain days when the schools are closed. """ def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) if year != 2009: days.append(self.get_lincoln_birthday(year)) days.append(( self.get_nth_weekday_in_month(year, 9, MON, 4), 'Native American Day' )) return days class CaliforniaBerkeley(California): """ Berkeley, California """ FIXED_HOLIDAYS = California.FIXED_HOLIDAYS + ( (5, 19, 'Malcolm X Day'), ) include_cesar_chavez_day = False include_lincoln_birthday = True include_columbus_day = True columbus_day_label = "Indigenous People's Day" class CaliforniaSanFrancisco(California): """ San Francisco, California """ include_cesar_chavez_day = False include_columbus_day = True class CaliforniaWestHollywood(California): """ West Hollywood, California """ FIXED_HOLIDAYS = California.FIXED_HOLIDAYS + ( (5, 22, 'Harvey Milk Day'), ) include_cesar_chavez_day = False include_thanksgiving_friday = False calendra-7.9.0/calendra/usa/colorado.py000066400000000000000000000003671457013633400200310ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-CO') class Colorado(UnitedStates): """Colorado""" # Colorado has only federal state holidays. # NOTE: Cesar Chavez Day is an optional holiday calendra-7.9.0/calendra/usa/connecticut.py000066400000000000000000000003341457013633400205370ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-CT') class Connecticut(UnitedStates): """Connecticut""" include_good_friday = True include_lincoln_birthday = True calendra-7.9.0/calendra/usa/core.py000066400000000000000000000241671457013633400171630ustar00rootroot00000000000000from datetime import date, timedelta from dateutil import relativedelta as rd from ..core import MON, SUN, THU, TUE, WesternCalendar from ..core import Holiday from ..registry_tools import iso_register @iso_register('US') class UnitedStates(WesternCalendar): "United States of America" FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( Holiday( date(2000, 7, 4), 'Independence Day', indication='July 4', ), ) @property def observance_shift(self): return Holiday.nearest_weekday # Veterans day label include_veterans_day = False veterans_day_label = 'Veterans Day' # MLK martin_luther_king_label = 'Birthday of Martin Luther King, Jr.' include_thanksgiving_friday = False thanksgiving_friday_label = "Thanksgiving Friday" # Some states don't include Washington's Birthday, or move it to December. include_federal_presidents_day = True presidents_day_label = "Washington's Birthday" include_lincoln_birthday = False # Columbus day is included by default include_columbus_day = True columbus_day_label = "Columbus Day" # Confederation day include_confederation_day = False # Jefferson Davis Birthday. include_jefferson_davis_birthday = False # Include Cesar Chavez day(s) include_cesar_chavez_day = False # Patriot's day include_patriots_day = False # Boxing day label is not "boxing day" in the US boxing_day_label = "Day After Christmas" # Election Day # To include every year? include_election_day_every_year = False # To include on even years? include_election_day_even = False # NOTE: if it's included on every year, it'll also be included # on even years. Setting these two flags to ON will give priority to the # yearly flag. election_day_label = "Election Day" # Inauguration Day include_inauguration_day = False # National Memorial Day national_memorial_day_label = "Memorial Day" # Some regional variants include_mardi_gras = False include_fat_tuesday = False fat_tuesday_label = "Mardi Gras" # Juneteenth include_juneteenth = False # Shift day mechanism # These days won't be shifted to next MON or previous FRI shift_exceptions = ( # Example: # (11, 11), # Veterans day won't be shifted ) @staticmethod def is_presidential_year(year): return (year % 4) == 0 def get_election_date(self, year): """ Return the Election Day *Date* Definition: on an election year, "the Tuesday next after the first Monday in the month of November". """ first_monday_november = self.get_nth_weekday_in_month(year, 11, MON) return self.get_nth_weekday_in_month( year, 11, TUE, start=first_monday_november ) def get_election_day(self, year): """ Return the Election Day """ return self.get_election_date(year), self.election_day_label def get_thanksgiving_friday(self, year): """ Thanksgiving friday is on the day following Thanksgiving Day """ thanksgiving = UnitedStates.get_nth_weekday_in_month(year, 11, THU, 4) thanksgiving_friday = thanksgiving + timedelta(days=1) return thanksgiving_friday, self.thanksgiving_friday_label def get_confederate_day(self, year): """ Confederate memorial day is on the 4th MON of April. """ day = self.get_nth_weekday_in_month(year, 4, MON, 4) return day, "Confederate Memorial Day" def get_jefferson_davis_birthday(self, year): """ The first MON of June is Jefferson Davis Birthday """ return ( self.get_nth_weekday_in_month(year, 6, MON, 1), "Jefferson Davis Birthday" ) def get_martin_luther_king_date(self, year): if year < 1985: raise ValueError( "Martin Luther King Day became a holiday in 1985" ) return date(year, 1, 1) + rd.relativedelta(weekday=rd.MO(3)) def get_martin_luther_king_day(self, year): """ Return holiday record for Martin Luther King Jr. Day. """ return Holiday( self.get_martin_luther_king_date(year), self.martin_luther_king_label, indication="3rd Monday in January", ) def get_presidents_day(self, year): """ Presidents Day is on the 3rd MON of February May be called Washington's or Lincoln's birthday """ return Holiday( date(year, 2, 1) + rd.relativedelta(weekday=rd.MO(3)), self.presidents_day_label, indication="3rd Monday in February", ) def get_cesar_chavez_days(self, year): """ Cesar Chavez day is on 31st of March Will return a list of days, because in some states (California), it can float to MON if it happens on SUN. """ days = [(date(year, 3, 31), "Cesar Chavez Day")] return days def get_patriots_day(self, year): """3rd Monday of April""" return self.get_nth_weekday_in_month(year, 4, MON, 3), "Patriots Day" def get_columbus_day(self, year): """ Columbus day is on the 2nd MON of October. Only half of the states recognize it. """ return Holiday( date(year, 10, 1) + rd.relativedelta(weekday=rd.MO(2)), self.columbus_day_label, indication="2nd Monday in October", ) def get_lincoln_birthday(self, year): """ February the 2nd is Lincoln's birthday in the following States: * Connecticut, * Illinois, * Missouri, * New York """ return date(year, 2, 12), "Lincoln's Birthday" def get_inauguration_date(self, year): """ If the year is an Inauguration Year, will return the Inauguration Day date. If this day falls on SUN, it's replaced by the next MON. If the year is not a Inauguration Year, it raises a ValueError. """ if ((year - 1) % 4) != 0: raise ValueError( f"The year {year} is not an Inauguration Year") inauguration_day = date(year, 1, 20) if inauguration_day.weekday() == SUN: inauguration_day = date(year, 1, 21) return inauguration_day def get_national_memorial_day(self, year): return Holiday( date(year, 5, 31) + rd.relativedelta(weekday=rd.MO(-1)), self.national_memorial_day_label, indication="Last Monday in May", ) def get_juneteenth_day(self, year): """ Return Juneteenth Day """ # Juneteenth started to be a federal holiday in 2021 if year < 2021: raise ValueError("Juneteenth became a federal holiday in 2021") return Holiday( date(year, 6, 19), "Juneteenth National Independence Day", indication="June 19th", ) def get_variable_days(self, year): # noqa: C901 # usual variable days days = super().get_variable_days(year) days += [ self.get_veterans_day(year), self.get_national_memorial_day(year), Holiday( date(year, 9, 1) + rd.relativedelta(weekday=rd.MO(1)), "Labor Day", indication="1st Monday in September", ), Holiday( date(year, 11, 1) + rd.relativedelta(weekday=rd.TH(4)), "Thanksgiving Day", indication="4th Thursday in November", ), ] # Martin Luther King's Day started only in 1985 if year >= 1985: days.append(self.get_martin_luther_king_day(year)) if self.include_mardi_gras: days.append(self.get_mardi_gras(year)) if self.include_federal_presidents_day: days.append(self.get_presidents_day(year)) if self.include_lincoln_birthday: days.append(self.get_lincoln_birthday(year)) if self.include_cesar_chavez_day: days.extend(self.get_cesar_chavez_days(year)) if self.include_patriots_day: days.append(self.get_patriots_day(year)) if self.include_columbus_day: days.append(self.get_columbus_day(year)) if self.include_confederation_day: days.append(self.get_confederate_day(year)) if self.include_jefferson_davis_birthday: days.append(self.get_jefferson_davis_birthday(year)) ind = "January 20 (or 21st if Sunday) following an election year" if self.include_inauguration_day: # Is it a "Inauguration year"? if UnitedStates.is_presidential_year(year - 1): days.append( Holiday( self.get_inauguration_date(year), "Inauguration Day", indication=ind, ), ) if self.include_election_day_every_year: days.append(self.get_election_day(year)) elif self.include_election_day_even: if (year % 2) == 0: days.append(self.get_election_day(year)) if self.include_thanksgiving_friday: days.append( self.get_thanksgiving_friday(year) ) if self.include_juneteenth and year >= 2021: days.append(self.get_juneteenth_day(year)) return days def get_veterans_day(self, year): """ Return Veterans Day (November 11th). Placed here because some States are renaming it. """ return Holiday( date(year, 11, 11), self.veterans_day_label, indication='Nov 11', ) def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.include_veterans_day: days.append(self.get_veterans_day(year)) return days class FederalReserveSystem(UnitedStates): "Board of Governors of the Federal Reserve System of the USA" include_juneteenth = True calendra-7.9.0/calendra/usa/delaware.py000066400000000000000000000005121457013633400200030ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-DE') class Delaware(UnitedStates): """Delaware""" include_good_friday = True include_thanksgiving_friday = True include_federal_presidents_day = False include_columbus_day = False include_election_day_even = True calendra-7.9.0/calendra/usa/district_columbia.py000066400000000000000000000004511457013633400217210ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-DC') class DistrictOfColumbia(UnitedStates): "District of Columbia" include_inauguration_day = True FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (4, 16, "Emancipation Day"), ) calendra-7.9.0/calendra/usa/florida.py000066400000000000000000000100761457013633400176450ustar00rootroot00000000000000from datetime import date, timedelta import warnings from pyluach.dates import GregorianDate from .core import UnitedStates from ..registry_tools import iso_register class HebrewHolidays: hebrew_calendars = {} @classmethod def get_hebrew_calendar(cls, gregorian_year): """ Build and cache the Hebrew calendar for the given Gregorian Year. """ if gregorian_year not in cls.hebrew_calendars: # Build the hebrew calendar for year days = [] current_date = date(gregorian_year, 1, 1) while current_date.year == gregorian_year: hebrew_date = GregorianDate( year=current_date.year, month=current_date.month, day=current_date.day, ).to_heb() days.append( (hebrew_date, current_date) ) current_date += timedelta(days=1) # Store it in the class property cls.hebrew_calendars[gregorian_year] = days # Return the hebrew calendar return cls.hebrew_calendars[gregorian_year] @classmethod def search_hebrew_calendar(cls, gregorian_year, hebrew_month, hebrew_day): """ Search for a specific Hebrew month and day in the Hebrew calendar. """ calendar = cls.get_hebrew_calendar(gregorian_year) search = filter(lambda item: item[0].month == hebrew_month, calendar) search = filter(lambda item: item[0].day == hebrew_day, search) for item in search: return item[1] @classmethod def get_rosh_hashanah(cls, year): """ Return the gregorian date of the first day of Rosh Hashanah """ return cls.search_hebrew_calendar(year, 7, 1) @classmethod def get_yom_kippur(cls, year): """ Return the gregorian date of Yom Kippur. """ return cls.search_hebrew_calendar(year, 7, 10) @iso_register('US-FL') class Florida(UnitedStates): """Florida""" include_thanksgiving_friday = True thanksgiving_friday_label = "Friday after Thanksgiving" include_columbus_day = False include_federal_presidents_day = False class FloridaLegal(Florida): """Florida Legal Holidays""" FIXED_HOLIDAYS = Florida.FIXED_HOLIDAYS + ( (2, 15, 'Susan B. Anthony Day'), (4, 2, 'Pascua Florida Day'), (6, 14, 'Flag Day'), ) include_fat_tuesday = True include_lincoln_birthday = True include_federal_presidents_day = True include_good_friday = True include_confederation_day = True include_jefferson_davis_birthday = True include_columbus_day = True columbus_day_label = "Columbus Day and Farmers' Day" include_election_day_every_year = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) warnings.warn( "Florida's laws separate the definitions between paid versus legal" " holidays. Be warned that Florida Legal specific Holidays are not" " paid holidays." ) def get_confederate_day(self, year): """ Confederation memorial day is on the April 26th for Florida Legal. """ return date(year, 4, 26), "Confederate Memorial Day" def get_jefferson_davis_birthday(self, year): """ Jefferson Davis Birthday appears to be a fixed holiday (June 3rd) """ return date(year, 6, 3), "Jefferson Davis Birthday" class FloridaCircuitCourts(HebrewHolidays, Florida): """Florida Circuits Courts""" include_federal_presidents_day = True include_good_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append(( self.get_rosh_hashanah(year), "Rosh Hashanah" )) days.append(( self.get_yom_kippur(year), "Yom Kippur" )) return days class FloridaMiamiDade(Florida): """Miami-Dade, Florida""" include_federal_presidents_day = True include_columbus_day = True calendra-7.9.0/calendra/usa/georgia.py000066400000000000000000000055621457013633400176460ustar00rootroot00000000000000import warnings from datetime import date from ..core import MON, TUE, WED, THU, FRI, SAT from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-GA') class Georgia(UnitedStates): """Georgia""" include_confederation_day = True include_federal_presidents_day = False label_washington_birthday_december = "Washington's Birthday (Observed)" thanksgiving_friday_label = "State Holiday" def get_washington_birthday_december(self, year): """ Washington birthday observance Similar to Christmas Eve, but with special rules. It's only observed in Georgia. """ warnings.warn( "Washington birthday rules for Georgia State are possibly wrong. " "Use this calendar with care") christmas_day = date(year, 12, 25).weekday() # Special case: 2011 / Source: # Christmas day is SUN, but doesn't follow the same rule as year 2016. # https://web.archive.org/web/20110927122533/http://www.georgia.gov/00/channel_modifieddate/0,2096,4802_64437763,00.html # noqa if year == 2011: day = date(year, 12, 26) elif christmas_day == MON: day = date(year, 12, 26) # TUE elif christmas_day == TUE: day = date(year, 12, 24) # MON elif christmas_day == WED: day = date(year, 12, 24) # TUE elif christmas_day == THU: day = date(year, 12, 26) # FRI elif christmas_day == FRI: day = date(year, 12, 24) # THU elif christmas_day == SAT: day = date(year, 12, 23) # THU else: # christmas_day == SUN: day = date(year, 12, 27) # FRI return day, self.label_washington_birthday_december def get_confederate_day(self, year): """ Confederate memorial day is on the 4th MON of April. Exception: Year 2020, when it happened on April 10th. """ if year >= 2016: label = "State Holiday" else: label = "Confederate Memorial Day" # At the moment, it's the only exception we know about. if year == 2020: return date(year, 4, 10), label day = self.get_nth_weekday_in_month(year, 4, MON, 4) return day, label def get_robert_lee_birthday(self, year): """ Robert E. Lee's birthday. Happens on the day after Thanksgiving. """ if year < 2016: label = "Robert E. Lee's Birthday (Observed)" else: label = "State Holiday" date, _ = self.get_thanksgiving_friday(year) return date, label def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ self.get_robert_lee_birthday(year), self.get_washington_birthday_december(year), ]) return days calendra-7.9.0/calendra/usa/guam.py000066400000000000000000000006411457013633400171530ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-GU') class Guam(UnitedStates): """Guam""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (3, 7, 'Guam History and Chamorro Heritage Day'), (7, 21, 'Liberation Day'), ) include_all_souls = True include_immaculate_conception = True immaculate_conception_label = "Lady of Camarin Day" calendra-7.9.0/calendra/usa/hawaii.py000066400000000000000000000014451457013633400174670ustar00rootroot00000000000000from ..core import FRI from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-HI') class Hawaii(UnitedStates): """Hawaii""" include_good_friday = True include_columbus_day = False include_election_day_even = True FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (3, 26, "Prince Jonah Kuhio Kalanianaole Day"), (6, 11, "King Kamehameha Day"), ) def get_statehood_day(self, year): """ Statehood Day: 3rd Friday in August. """ return ( self.get_nth_weekday_in_month(year, 8, FRI, 3), "Statehood Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_statehood_day(year)) return days calendra-7.9.0/calendra/usa/idaho.py000066400000000000000000000003561457013633400173110ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-ID') class Idaho(UnitedStates): """Idaho""" martin_luther_king_label = ( "Martin Luther King Jr. / Idaho Human Rights Day" ) calendra-7.9.0/calendra/usa/illinois.py000066400000000000000000000015551457013633400200510ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register from ..core import MON @iso_register('US-IL') class Illinois(UnitedStates): """Illinois""" include_thanksgiving_friday = True include_lincoln_birthday = True include_election_day_even = True class ChicagoIllinois(Illinois): "Chicago, Illinois" include_thanksgiving_friday = False def get_pulaski_day(self, year): """ Return Casimir Pulaski Day. Defined on the first MON of March. ref: https://en.wikipedia.org/wiki/Casimir_Pulaski_Day """ day = self.get_nth_weekday_in_month(year, 3, MON) return ( day, "Casimir Pulaski Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append(self.get_pulaski_day(year)) return days calendra-7.9.0/calendra/usa/indiana.py000066400000000000000000000045711457013633400176330ustar00rootroot00000000000000import warnings from datetime import date from ..core import MON, TUE, WED, THU, FRI, SAT from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-IN') class Indiana(UnitedStates): """Indiana""" include_good_friday = True include_thanksgiving_friday = True thanksgiving_friday_label = "Lincoln's Birthday" include_federal_presidents_day = False label_washington_birthday_december = "Washington's Birthday (Observed)" include_election_day_even = True election_day_label = "General Election Day" def get_washington_birthday_december(self, year): """ Washington birthday observance Similar to Christmas Eve, but with special rules. It's only observed in Georgia. """ warnings.warn( "Washington birthday rules for Indiana State are confusing. " "Use this calendar with care") christmas_day = date(year, 12, 25).weekday() if christmas_day == MON: day = date(year, 12, 26) # TUE elif christmas_day == TUE: day = date(year, 12, 24) # MON elif christmas_day == WED: day = date(year, 12, 26) # TUE elif christmas_day == THU: day = date(year, 12, 26) # FRI elif christmas_day == FRI: day = date(year, 12, 24) # THU elif christmas_day == SAT: day = date(year, 12, 23) # THU else: # christmas_day == SUN: day = date(year, 12, 23) # FRI return day, self.label_washington_birthday_december def get_primary_election_day(self, year): """ Return the Primary Election Day FIXME: Wikipedia says it's a floating MON, but other sources say it's "the first Tuesday after the first Monday of May and every two years thereafter". """ first_monday_may = self.get_nth_weekday_in_month(year, 5, MON) tuesday_after = self.get_nth_weekday_in_month( year, 5, TUE, start=first_monday_may) return ( tuesday_after, "Primary Election Day" ) def get_variable_days(self, year): days = super().get_variable_days(year) days.extend([ self.get_washington_birthday_december(year), ]) if (year % 2) == 0: days.append(self.get_primary_election_day(year)) return days calendra-7.9.0/calendra/usa/iowa.py000066400000000000000000000003761457013633400171660ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-IA') class Iowa(UnitedStates): """Iowa""" include_thanksgiving_friday = True include_columbus_day = False include_federal_presidents_day = False calendra-7.9.0/calendra/usa/kansas.py000066400000000000000000000014561457013633400175070ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register # FIXME: According to wikipedia, Kansas only has all federal holidays, except # the Columbus Day and Washington's Birthday. # Unfortunately, other sources mention XMas Eve for 2018, but not for other # years. # I'm a bit sad here... # # Sources to lookup, if you want to help: # * http://www.admin.ks.gov/docs/default-source/ops/holidays/holidays2018.pdf # * http://www.kansas.gov/employee/documents/2017calendar.pdf # * https://publicholidays.us/kansas/2018-dates/ # * https://en.wikipedia.org/wiki/Public_holidays_in_the_United_States#Kansas # * https://publicholidays.us/kansas/2018-dates/ @iso_register('US-KS') class Kansas(UnitedStates): """Kansas""" include_federal_presidents_day = False include_columbus_day = False calendra-7.9.0/calendra/usa/kentucky.py000066400000000000000000000006451457013633400200630ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-KY') class Kentucky(UnitedStates): """Kentucky""" include_good_friday = True include_thanksgiving_friday = True include_christmas_eve = True include_columbus_day = False include_federal_presidents_day = False FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (12, 31, "New Year's Eve"), ) calendra-7.9.0/calendra/usa/louisiana.py000066400000000000000000000004311457013633400202030ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-LA') class Louisiana(UnitedStates): """Louisiana""" include_good_friday = True include_election_day_even = True include_columbus_day = False include_fat_tuesday = True calendra-7.9.0/calendra/usa/maine.py000066400000000000000000000003241457013633400173110ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-ME') class Maine(UnitedStates): """Maine""" include_thanksgiving_friday = True include_patriots_day = True calendra-7.9.0/calendra/usa/maryland.py000066400000000000000000000007111457013633400200270ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-MD') class Maryland(UnitedStates): """Maryland""" thanksgiving_friday_label = "Native American Heritage Day" include_thanksgiving_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) if Maryland.is_presidential_year(year): days.append(self.get_election_day(year)) return days calendra-7.9.0/calendra/usa/massachusetts.py000066400000000000000000000006321457013633400211110ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-MA') class Massachusetts(UnitedStates): """Massachusetts""" include_patriots_day = True class SuffolkCountyMassachusetts(Massachusetts): """Suffolk County, Massachusetts""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (3, 17, 'Evacuation Day'), (6, 17, 'Bunker Hill Day'), ) calendra-7.9.0/calendra/usa/michigan.py000066400000000000000000000016651457013633400200100ustar00rootroot00000000000000from datetime import date from ..core import SUN from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-MI') class Michigan(UnitedStates): """Michigan""" include_christmas_eve = True include_thanksgiving_friday = True include_election_day_even = True include_columbus_day = False def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) # New Year's Eve to be added new_years_eve = date(year, 12, 31) days.append( (new_years_eve, "New Years Eve") ) # Christmas Eve & New Year's Eve shift when it falls on SUN xmas_eve = date(year, 12, 24) if xmas_eve.weekday() == SUN: days.append( (date(year, 12, 22), "Christmas Eve shift") ) days.append( (date(year, 12, 29), "New Years Eve Shift") ) return days calendra-7.9.0/calendra/usa/minnesota.py000066400000000000000000000003351457013633400202170ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-MN') class Minnesota(UnitedStates): """Minnesota""" include_thanksgiving_friday = True include_columbus_day = False calendra-7.9.0/calendra/usa/mississippi.py000066400000000000000000000010651457013633400205770ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-MS') class Mississippi(UnitedStates): """Mississippi""" include_thanksgiving_friday = True include_confederation_day = True include_columbus_day = False martin_luther_king_label = ("Martin Luther King's" " and Robert E. Lee's Birthdays") veterans_day_label = "Armistice Day (Veterans Day)" national_memorial_day_label = ("National Memorial Day / " "Jefferson Davis Birthday") calendra-7.9.0/calendra/usa/missouri.py000066400000000000000000000004201457013633400200670ustar00rootroot00000000000000from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-MO') class Missouri(UnitedStates): """Missouri""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (5, 8, "Truman Day"), ) include_lincoln_birthday = True calendra-7.9.0/calendra/usa/montana.py000066400000000000000000000010061457013633400176530ustar00rootroot00000000000000import warnings from .core import UnitedStates from ..registry_tools import iso_register @iso_register('US-MT') class Montana(UnitedStates): """Montana""" include_election_day_even = True def get_variable_days(self, year): warnings.warn( "Montana states is supposed to observe General Election Day on " "even years, but for some reason some sources are including it " "in 2019. Please use with care." ) return super().get_variable_days(year) calendra-7.9.0/calendra/usa/nebraska.py000066400000000000000000000006431457013633400200120ustar00rootroot00000000000000from ..core import FRI from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NE') class Nebraska(UnitedStates): """Nebraska""" include_thanksgiving_friday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_last_weekday_in_month(year, 4, FRI), "Arbor Day") ) return days calendra-7.9.0/calendra/usa/nevada.py000066400000000000000000000007571457013633400174700ustar00rootroot00000000000000from ..core import FRI from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NV') class Nevada(UnitedStates): """Nevada""" include_thanksgiving_friday = True thanksgiving_friday_label = "Family Day" include_columbus_day = False def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_last_weekday_in_month(year, 10, FRI), "Nevada Day") ) return days calendra-7.9.0/calendra/usa/new_hampshire.py000066400000000000000000000004151457013633400210520ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NH') class NewHampshire(UnitedStates): """New Hampshire""" include_thanksgiving_friday = True martin_luther_king_label = "Martin Luther King, Jr. Civil Rights Day" calendra-7.9.0/calendra/usa/new_jersey.py000066400000000000000000000003401457013633400203700ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NJ') class NewJersey(UnitedStates): """New Jersey""" include_good_friday = True include_election_day_every_year = True calendra-7.9.0/calendra/usa/new_mexico.py000066400000000000000000000004321457013633400203550ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NM') class NewMexico(UnitedStates): """New Mexico""" include_thanksgiving_friday = True thanksgiving_friday_label = "Presidents' Day" include_federal_presidents_day = False calendra-7.9.0/calendra/usa/new_york.py000066400000000000000000000003411457013633400200540ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NY') class NewYork(UnitedStates): """New York""" include_lincoln_birthday = True include_election_day_every_year = True calendra-7.9.0/calendra/usa/north_carolina.py000066400000000000000000000032071457013633400212250ustar00rootroot00000000000000from datetime import date from ..core import MON, TUE, WED, THU, FRI, SAT, SUN from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-NC') class NorthCarolina(UnitedStates): """North Carolina""" include_good_friday = True include_christmas_eve = True include_thanksgiving_friday = True include_boxing_day = True include_federal_presidents_day = False include_columbus_day = False def get_christmas_shifts(self, year): """ Return Specific Christmas days extra shifts. There must be 3 holidays in a row: Christmas Eve, Christmas Day and Boxing Day. If one or the other falls on SUN/SAT, extra days must be added. """ xmas = date(year, 12, 25) if xmas.weekday() in (TUE, WED, THU): # No shift, move along return [] if xmas.weekday() == FRI: return [ (date(year, 12, 28), "Boxing day shift"), ] elif xmas.weekday() == SAT: return [ (date(year, 12, 23), "Christmas Eve shift"), (date(year, 12, 27), "Boxing Day shift"), ] elif xmas.weekday() == SUN: return [ (date(year, 12, 23), "Christmas Eve shift"), (date(year, 12, 27), "Boxing Day shift"), ] elif xmas.weekday() == MON: return [ (date(year, 12, 27), "Christmas Eve shift"), ] def get_variable_days(self, year): days = super().get_variable_days(year) days.extend(self.get_christmas_shifts(year)) return days calendra-7.9.0/calendra/usa/north_dakota.py000066400000000000000000000006621457013633400207020ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-ND') class NorthDakota(UnitedStates): """North Dakota""" include_columbus_day = False include_good_friday = True # NOTE: At the time of writing, the Public Holidays for USA wikipedia page # doesn't mention Good Friday, although the official Secretary of State page # does: http://sos.nd.gov/about-office/holiday-office-closings calendra-7.9.0/calendra/usa/ohio.py000066400000000000000000000004331457013633400171570ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-OH') class Ohio(UnitedStates): """Ohio""" # NOTE: Ohio includes only Federal holidays. # The wikipedia page say it also includes Election Day, but no official # document confirms this. calendra-7.9.0/calendra/usa/oklahoma.py000066400000000000000000000003711457013633400200150ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-OK') class Oklahoma(UnitedStates): """Oklahoma""" include_thanksgiving_friday = True include_boxing_day = True include_columbus_day = False calendra-7.9.0/calendra/usa/oregon.py000066400000000000000000000002601457013633400175100ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-OR') class Oregon(UnitedStates): """Oregon""" include_columbus_day = False calendra-7.9.0/calendra/usa/pennsylvania.py000066400000000000000000000004141457013633400207270ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-PA') class Pennsylvania(UnitedStates): """Pennsylvania""" include_good_friday = True include_thanksgiving_friday = True include_election_day_every_year = True calendra-7.9.0/calendra/usa/rhode_island.py000066400000000000000000000007271457013633400206620ustar00rootroot00000000000000from ..core import MON from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-RI') class RhodeIsland(UnitedStates): """Rhode Island""" include_federal_presidents_day = False include_election_day_even = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_nth_weekday_in_month(year, 8, MON, 2), "Victory Day") ) return days calendra-7.9.0/calendra/usa/south_carolina.py000066400000000000000000000006151457013633400212350ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-SC') class SouthCarolina(UnitedStates): """South Carolina""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (5, 10, "Confederate Memorial Day"), ) include_thanksgiving_friday = True include_christmas_eve = True include_boxing_day = True include_columbus_day = False calendra-7.9.0/calendra/usa/south_dakota.py000066400000000000000000000004741457013633400207130ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-SD') class SouthDakota(UnitedStates): """South Dakota""" columbus_day_label = "Native Americans Day" # NOTE: South Dakota has all federal holidays, except Columbus Day, # but it's renamed as "Native Americans Day" calendra-7.9.0/calendra/usa/tennessee.py000066400000000000000000000003671457013633400202200ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-TN') class Tennessee(UnitedStates): """Tennessee""" include_columbus_day = False include_good_friday = True include_christmas_eve = True calendra-7.9.0/calendra/usa/texas.py000066400000000000000000000061021457013633400173440ustar00rootroot00000000000000""" Texas module ============ This module presents two classes to handle the way state holidays are managed in Texas. The :class:`TexasBase` class gathers all available holidays for Texas, according to this document: http://www.statutes.legis.state.tx.us/Docs/GV/htm/GV.662.htm The :class:`Texas` class includes all national and state holidays, as described in the said document. This should be the "default" Texas calendar class, to be used in most cases. But if state holidays are supposed to be observed by most of the workforces, any employee can chose to skip one of these days and replace it by another. If at some point you need to create a specific calendar class based on Texas calendar, you can either use the :class:`TexasBase` class or directly the :class:`Texas` class and overwrite/override the :method:`get_fixed_holidays()` and/or :method:`get_variable_days()` to fit your needs. Example: .. code:: class TexasCustom(TexasBase): # This will include the confederate heroes day texas_include_confederate_heroes = True FIXED_HOLIDAYS = TexasBase.FIXED_HOLIDAYS + ( (7, 14, "Bastille Day!"), ) def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_nth_weekday_in_month(year, 1, 15), "Special Day") ) return days """ from datetime import date from ..registry_tools import iso_register from .core import UnitedStates class TexasBase(UnitedStates): """Texas Base (w/o State holidays)""" include_columbus_day = False texas_include_confederate_heroes = False texas_include_independance_day = False texas_san_jacinto_day = False texas_emancipation_day = False texas_lyndon_johnson_day = False # Non-Texas-specific state holidays include_thanksgiving_friday = False include_christmas_eve = False include_boxing_day = False def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.texas_include_confederate_heroes: days.append( (date(year, 1, 19), "Confederate Heroes Day") ) if self.texas_include_independance_day: days.append( (date(year, 3, 2), "Texas Independence Day") ) if self.texas_san_jacinto_day: days.append( (date(year, 4, 21), "San Jacinto Day") ) if self.texas_emancipation_day: days.append( (date(year, 6, 19), "Emancipation Day in Texas"), ) if self.texas_lyndon_johnson_day: days.append( (date(year, 8, 27), "Lyndon B. Jonhson Day"), ) return days @iso_register('US-TX') class Texas(TexasBase): """Texas""" texas_include_confederate_heroes = True texas_include_independance_day = True texas_san_jacinto_day = True texas_emancipation_day = True texas_lyndon_johnson_day = True include_thanksgiving_friday = True include_christmas_eve = True include_boxing_day = True calendra-7.9.0/calendra/usa/utah.py000066400000000000000000000003461457013633400171650ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-UT') class Utah(UnitedStates): """Utah""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (7, 24, "Pioneer Day"), ) calendra-7.9.0/calendra/usa/vermont.py000066400000000000000000000010261457013633400177120ustar00rootroot00000000000000from ..core import TUE from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-VT') class Vermont(UnitedStates): """Vermont""" FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (8, 16, "Bennington Battle Day"), ) include_columbus_day = False def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_nth_weekday_in_month(year, 3, TUE, 1), "Town Meeting Day") ) return days calendra-7.9.0/calendra/usa/virginia.py000066400000000000000000000023421457013633400200320ustar00rootroot00000000000000""" Virginia module You may or may want not to treat the Day before Thanksgiving as a non-working day by implementing the following class: .. code:: from workalenda.usa import Virginia as VirginiaBase class Virginia(VirginiaBase): include_thanksgiving_wednesday = False """ from ..core import WED, FRI from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-VA') class Virginia(UnitedStates): """Virginia""" include_christmas_eve = True include_thanksgiving_friday = True include_boxing_day = True presidents_day_label = "George Washington Day" # Virginia specific. By default, it's treated as a holiday, but # you may chose to exclude it for you own uses. See the module doc. include_thanksgiving_wednesday = True def get_variable_days(self, year): days = super().get_variable_days(year) days.append( (self.get_nth_weekday_in_month(year, 1, FRI, 3), "Lee-Jackson Day") ) if self.include_thanksgiving_wednesday: days.append( (self.get_nth_weekday_in_month(year, 11, WED, 4), "Day before Thanksgiving (start at noon)") ) return days calendra-7.9.0/calendra/usa/washington.py000066400000000000000000000002701457013633400204010ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-WA') class Washington(UnitedStates): """Washington""" include_columbus_day = False calendra-7.9.0/calendra/usa/west_virginia.py000066400000000000000000000025741457013633400211030ustar00rootroot00000000000000""" West Virginia Christmas Eve and New Years Eve are considered as half-holidays. By default, they're not included as "non-working days". If for your personal use you want to include them, you may just have to create a class like this: .. code:: class WestVirginiaIncludeEves(WestVirginia): west_virginia_include_christmas_eve = True west_virginia_include_nye = True """ from datetime import date from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-WV') class WestVirginia(UnitedStates): """West Virginia""" include_thanksgiving_friday = True include_election_day_even = True election_day_label = "Election Day / Susan B. Anthony Day" # West Virginia specific "half-holidays" west_virginia_include_christmas_eve = False west_virginia_include_nye = False FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (6, 20, "West Virgina Day"), ) shift_exceptions = ( (12, 24), (12, 31), ) def get_fixed_holidays(self, year): days = super().get_fixed_holidays(year) if self.west_virginia_include_christmas_eve: days.append( (date(year, 12, 24), "Christmas Eve") ) if self.west_virginia_include_nye: days.append( (date(year, 12, 31), "New Years Eve") ) return days calendra-7.9.0/calendra/usa/wisconsin.py000066400000000000000000000005401457013633400202340ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-WI') class Wisconsin(UnitedStates): """Wisconsin""" include_columbus_day = False include_federal_presidents_day = False include_christmas_eve = True FIXED_HOLIDAYS = UnitedStates.FIXED_HOLIDAYS + ( (12, 31, "New Years Eve"), ) calendra-7.9.0/calendra/usa/wyoming.py000066400000000000000000000003411457013633400177100ustar00rootroot00000000000000from ..registry_tools import iso_register from .core import UnitedStates @iso_register('US-WY') class Wyoming(UnitedStates): """Wyoming""" martin_luther_king_label = "Martin Luther King, Jr. / Wyoming Equality Day" calendra-7.9.0/docs/000077500000000000000000000000001457013633400142365ustar00rootroot00000000000000calendra-7.9.0/docs/advanced.md000066400000000000000000000071201457013633400163250ustar00rootroot00000000000000# Advanced usage [Home](index.md) / [Basic usage](basic.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) The following examples will better suit people willing to contribute to Calendra or building their custom calendars. They use primitives and methods attached to the core Calendar class to enable computation of complex holidays, that is to say dates that are not fixed, not related to religious calendars (Christmas always happens on December 25th, right?). ## Find the following working day after a date It's a bit like a shortcut function to find the next working day after the given date. Please note that if the day you're entering is already a working day, that'll be the returned result. ```python >>> from datetime import date, datetime >>> from calendra.europe import France >>> cal = France() >>> cal.find_following_working_day(date(2018, 7, 6)) # It's FRI datetime.date(2018, 7, 6) >>> cal.find_following_working_day(date(2018, 7, 7)) # SAT => next MON datetime.date(2018, 7, 9) ``` **WARNING**: this function doesn't take into account the existing holidays in the calendar. If you need this, use the ``add_working_days()`` function as described in the [Basic usage document](basic.md). ## Find the 4th Thursday in November That's a puzzling question that we needed to address when we had to implement United States of America holidays calendars. Thanksgiving day, for example, which is on the 4th Thursday in November (Thanksgiving Friday is the day after this thursday)... and many others, are defined as: > the ``nth`` ``Weekday name`` of the month of ``Month name`` Or even better for Election day, which is: > the Tuesday next after the first Monday in the month of November. We've got you covered with static methods in the core ``Calendar`` class. ```python >>> from calendra.core import Calendar, THU >>> Calendar.get_nth_weekday_in_month(2018, 11, THU) # by default, find the first datetime.date(2018, 11, 2) >>> Calendar.get_nth_weekday_in_month(2018, 11, THU, 4) # Thanksgiving datetime.date(2018, 11, 23) ``` If you want to find the 2nd Monday after the 4th of July, you can use the ``start`` argument: ```python >>> from datetime import date >>> from calendra.core import Calendar, MON >>> Calendar.get_nth_weekday_in_month( 2018, # Year 7, # Month MON, # Monday 2, # The 2nd one start=date(2018, 7, 9)) datetime.date(2018, 7, 16) ``` ## Find the last Monday in the Month This one was a bit trickier, because it may happen that you have 4 or 5 `weekday name` in the same month. e.g: during the month of July 2018, you have 5 Mondays (2nd, 9th, 16th, 23rd, 30th), but only 4 Saturdays (7th, 14th, 21st, 28th). Same as above, there's a static method in the ``Calendar`` class: ```python >>> from calendra.core import Calendar, MON, FRI >>> Calendar.get_last_weekday_in_month(2018, 7, MON) datetime.date(2018, 7, 30) >>> Calendar.get_last_weekday_in_month(2018, 7, FRI) datetime.date(2018, 7, 27) ``` ## Find the first Monday after a given date Colombia, as an example, states that the Epiphany Day is set to the "First Monday after the 6th of January". You may use the following function to find this specific formula: ```python >>> from calendra.core import Calendar, MON >>> from datetime import date >>> jan_6th = date(2018, 1, 6) # It's a Saturday >>> Calendar.get_first_weekday_after(jan_6th, MON) datetime.date(2018, 1, 8) ``` [Home](index.md) / [Basic usage](basic.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) calendra-7.9.0/docs/basic.md000066400000000000000000000105671457013633400156520ustar00rootroot00000000000000# Basic usage [Home](index.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) Here are basic examples of what Calendra can do for you. As an integrator or a simple Calendra user, you will use these methods to retrieve calendars, and get basic outputs for a given date. ## Get holidays for a given country and year ```python >>> from calendra.europe import France >>> cal = France() >>> cal.holidays(2012) [(datetime.date(2012, 1, 1), 'New year'), (datetime.date(2012, 4, 9), 'Easter Monday'), (datetime.date(2012, 5, 1), 'Labour Day'), (datetime.date(2012, 5, 8), 'Victory in Europe Day'), (datetime.date(2012, 5, 17), 'Ascension Day'), (datetime.date(2012, 5, 28), 'Whit Monday'), (datetime.date(2012, 7, 14), 'Bastille Day'), (datetime.date(2012, 8, 15), 'Assumption of Mary to Heaven'), (datetime.date(2012, 11, 1), "All Saints' Day"), (datetime.date(2012, 11, 11), 'Armistice Day'), (datetime.date(2012, 12, 25), 'Christmas')] ``` As you can see, the output is a simple list of tuples, with the first member being a `datetime.date` object, and the second one is the holiday label as a string. By design, we have chosen to stick to basic types so you can use them in your application and eventually compose your personal classes using them. ## Know if a day is a holiday or not ```python >>> from datetime import date >>> from calendra.europe import France >>> cal = France() >>> cal.is_working_day(date(2012, 12, 25)) # it's Christmas False >>> cal.is_working_day(date(2012, 12, 30)) # it's a Sunday False >>> cal.is_working_day(date(2012, 12, 26)) # No Boxing day in France True ``` ## Compute the "nth" working day after a given date That was the basic use-case that started this library development: to answer to the following question: > This task is due in 5 working days, starting of today. Can we calculate that? In the following example, we want to calculate 5 working days after December the 23rd 2012. | Date | Weekday | Working Day? | Count | |:-----|:-------:|:------------:|:-----:| | 23rd | SUN | No | 0 | | 24th | MON | Yes | +1 | | 25th | TUE | No (XMas) | - | | 26th | WED | Yes | +2 | | 27th | THU | Yes | +3 | | 28th | FRI | Yes | +4 | | 29th | SAT | No (weekend) | - | | 30th | SUN | No (weekend) | - | | 31th | MON | Yes | +5 | ```python >>> from datetime import date >>> from calendra.europe import France >>> cal = France() >>> cal.add_working_days(date(2012, 12, 23), 5) datetime.date(2012, 12, 31) ``` If we had requested the 6th day after the 23rd, it would have been January 2nd, 2013, because January 1st is New Year's Day. ## Calculate the number or working days between two given days Let's say you want to know how many working days there are between April 2nd and June 17th of 2018, in France. Use the following: ```python >>> from datetime import date >>> from calendra.europe import France >>> cal = France() >>> cal.get_working_days_delta(date(2018, 4, 2), date(2018, 6, 17)) 50 ``` ## Standard date(time) types only, please! For your convenience, we allow both `datetime.date` and `datetime.datetime` types (and their subclasses) when using the core functions. **WARNING**: We'll only allow "dates" types coming from the Python standard library. If you're manipulating types from external library. Trying to pass a non-standard argument will result in raising a ``UnsupportedDateType`` error. Example: ```python >>> from datetime import date, datetime >>> from calendra.europe import France >>> cal = France() >>> cal.is_working_day(datetime(2012, 12, 25, 14, 0, 39)) False >>> cal.add_working_days(datetime(2012, 12, 23, 14, 0, 39), 5) datetime.date(2012, 12, 31) ``` You see that the default result type is ``datetime.date``. But if you really need it, you can use the ``keep_datetime`` option to return the result with the input type: ```python >>> from datetime import date, datetime >>> from calendra.europe import France >>> cal = France() >>> cal.add_working_days(datetime(2012, 12, 23, 14, 0, 39), 5, keep_datetime=True) datetime.datetime(2012, 12, 31, 14, 0, 39) ``` [Home](index.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) calendra-7.9.0/docs/class-options.md000066400000000000000000000107601457013633400173620ustar00rootroot00000000000000# Advanced feature: class options [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) As of `v13.0.0` you can define *options* for your calendar. ## Options as "flags" Let's consider the following calendar class: ```python @iso_register('ZK') class Zhraa(WesternCalendar): include_easter_monday = True include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (8, 2, "King Birthday"), ) def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) days.append( (Zhraa.get_nth_weekday_in_month(year, 6, MON), 'Day of the Founder'), ) return days ``` In our example, we'll add a special holiday. It's **not** an official holiday, but it **can** be taken as a non-working day, if your organization or your administration decides it becomes one. For the sake of our use-case, let's say that the Zhraa Kingdom decides that January the 2nd can be considered as a day off in some special cases, for banks or schools, for example. Or at the discretion of your company. As an integrator, if you need to implement this behaviour, you can decide to have a separate class which includes your extra day. This would fit your needs. But what if your special organization decides to keep this day as a non-working day depending on a variable context? Let's say that it does not happen every year, or it's not in every city of the Kingdom, or not for all of your employees, etc. Using a dedicated class won't help you there. But **optional arguments** surely will! Here's a slightly different version of our `Zhraa` class: ```python @iso_register('ZK') class Zhraa(WesternCalendar): include_easter_monday = True include_labour_day = True FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + ( (8, 2, "King Birthday"), ) def __init__(self, include_january_2nd=False, **kwargs): super().__init__(**kwargs) self.include_january_2nd = include_january_2nd def get_variable_days(self, year): # usual variable days days = super().get_variable_days(year) days.append( (Zhraa.get_nth_weekday_in_month(year, 6, MON), 'Day of the Founder'), ) if self.include_january_2nd: days.append( (date(year, 1, 2), "January 2nd") ) return days ``` In your *business-logic code*, you could then write: ```python include_january_2nd = year == 2019 \ and (employee_name == "Bob" or employee_location == "North") calendar = Zhraa(include_january_2nd=include_january_2nd) ``` As a consequence, depending on the context required by your business-logic process, you can include or exclude January 2nd as a holiday. ## More than "flags" Of course, **you are not limited to booleans** to activate/deactivate a holiday when you want to create options. Use strings, numbers, objects, or whatever suits your needs. Here are some examples: * A ``region`` argument: in some regions, it defines new holidays, exceptions on including or excluding other days, etc. * A `number_of_days_after_new_year` as a variable number of days that are to be accounted as non-working days after New Year's day. * A ``day_of_the_founder_label`` string variable to easily customize the *Day of the Founder* label, according to your liking. * ... sky is the limit! ## Caveats ### Why not using derivative classes? Again, for each of these options, you could define an inherited class of `Zhraa`. But as you have more and more option values and exceptions to your rules, you'd have to define a new class for each of these combinations. If you only have a couple of exceptions to your rules, you may prefer ot have a dedicated class. If the number of combinations goes over a limit, opt for *options*. ### ERR_TOO_MANY_OPTIONS **Beware!** Options are nice and will help you in many cases, but it's probably a bad idea to go on and add dozens of them to your class constructor. As a consequence, your runtime code would be more and more complex. You'd have hard time covering all of the combinations around their values and test them. As in many other cases, your mileage may vary, but I doubt that you want to combine more than 5 of them. [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [ISO Registry](iso-registry.md) / [iCal Export](ical.md) / [Contributing](contributing.md) calendra-7.9.0/docs/conf.py000066400000000000000000000027651457013633400155470ustar00rootroot00000000000000extensions = [ 'sphinx.ext.autodoc', 'jaraco.packaging.sphinx', ] master_doc = "index" html_theme = "furo" # Link dates and other references in the changelog extensions += ['rst.linker'] link_files = { '../NEWS.rst': dict( using=dict( GH='https://github.com', workalendar='https://github.com/workalendar/workalendar/', ), replace=[ dict( pattern=r'(Issue #|\B#)(?P\d+)', url='{package_url}/issues/{issue}', ), dict( pattern=r'(?m:^((?Pv?\d+(\.\d+){1,2}))\n[-=]+\n)', with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n', ), dict( pattern=r'PEP[- ](?P\d+)', url='https://peps.python.org/pep-{pep_number:0>4}/', ), dict( pattern=r'\(#(?P\d+)(.*?)\)', url='{workalendar}issues/{wk_issue}', ), dict( pattern=r'(?P[Ww]orkalendar \d+\.\d+(\.\d+)?)', url='{workalendar}blob/master/Changelog.md', ), ], ) } # Be strict about any broken references nitpicky = True # Include Python intersphinx mapping to prevent failures # jaraco/skeleton#51 extensions += ['sphinx.ext.intersphinx'] intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), } # Preserve authored syntax for defaults autodoc_preserve_defaults = True calendra-7.9.0/docs/history.rst000066400000000000000000000001161457013633400164670ustar00rootroot00000000000000:tocdepth: 2 .. _changes: History ******* .. include:: ../NEWS (links).rst calendra-7.9.0/docs/ical.md000066400000000000000000000050411457013633400154700ustar00rootroot00000000000000# iCal export [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [Contributing](contributing.md) As of v11.0.0, you can export holidays generated by any Workalendar class to the iCal file format. ## Export and retrieve the content In this example, we export all the public holidays for France from the year 2019 to the year 2022 (inclusive). ```python >>> from workalendar.europe import France >>> cal = France() >>> ical_content = cal.export_to_ical(period=[2019, 2022]) >>> print(ical_content) BEGIN:VCALENDAR VERSION:2.0 PRODID:-//workalendar//ical 9.0.0//EN BEGIN:VEVENT SUMMARY:New year DTSTART;VALUE=DATE:20190101 DTSTAMP;VALUE=DATE-TIME:20200828T152009Z UID:2019-01-01New year@peopledoc.github.io/workalendar END:VEVENT BEGIN:VEVENT SUMMARY:Easter Monday DTSTART;VALUE=DATE:20190422 DTSTAMP;VALUE=DATE-TIME:20200828T152009Z UID:2019-04-22Easter Monday@peopledoc.github.io/workalendar END:VEVENT BEGIN:VEVENT SUMMARY:Labour Day DTSTART;VALUE=DATE:20190501 DTSTAMP;VALUE=DATE-TIME:20200828T152009Z UID:2019-05-01Labour Day@peopledoc.github.io/workalendar END:VEVENT # ... ``` You may store this content into a file, or do anything else you want with it. If you don't provide any period, it defaults to [2000, 2030]. ## Export and save it to a file You can also directly save your ical export to a file. The following example writes a ``france.ics`` file to your disk, with the holidays between 2019 and 2022. ```python >>> from workalendar.europe import France >>> cal = France() >>> cal.export_to_ical(period=[2019, 2022], target_path="france.ics") ``` **Note:** Please note that the export function won't work if the path is unwriteable or if it points at an existing directory. ### Known file extensions The `target_path` argument may be provided with or without a file extension. For example, it can be either: | `target_path` argument | filename generated | |:-----------------------|:-------------------| | `france` | `france.ics` | | `france.ics` | `france.ics` | | `france.ical` | `france.ical` | | `france.ifb` | `france.ifb` | | `france.icalendar` | `france.icalendar` | | `france.txt` | `france.txt.ics` | As you see, we only add the `.ics` extension if the current `target_path` extension is not known. [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [ISO Registry](iso-registry.md) / [Contributing](contributing.md) calendra-7.9.0/docs/index.md000066400000000000000000000014461457013633400156740ustar00rootroot00000000000000# Calendra documentation ## Overview Calendra is a Python module that offers classes able to handle calendars, list legal / religious holidays and gives working-day-related computation functions. ## Status This library is ready for production, although we may warn eventual users: some calendars may not be up-to-date, and this library doesn't cover all the existing countries on earth (yet). ## Available Calendars See [the repository README](https://github.com/jaraco/calendra#available-calendars) for the most up-to-date catalog of the available calendars. ## Usage examples * [Basic usage](basic.md) * [Advanced usage](advanced.md) * Advanced features: * [Class options](class-options.md) * [ISO Registry](iso-registry.md) * [iCal Export](ical.md) * [How to contribute](contributing.md) calendra-7.9.0/docs/index.rst000066400000000000000000000006461457013633400161050ustar00rootroot00000000000000Welcome to |project| documentation! =================================== .. sidebar-links:: :home: :pypi: .. toctree:: :maxdepth: 1 history See the `workalendar docs `_ for more details. .. automodule:: calendra :members: :undoc-members: :show-inheritance: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` calendra-7.9.0/docs/iso-registry.md000066400000000000000000000160341457013633400172240ustar00rootroot00000000000000# The ISO registry [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [iCal Export](ical.md) / [Contributing](contributing.md) As of version 3.0 (August/September 2018), we have introduced a global calendar registry for calendars related to a country or a region that belongs to the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) or the [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) for sub-regions (such as USA states, Australian territories or Canadian provinces and such). ## Iterate over the whole registry ```python >>> from workalendar.registry import registry >>> calendars = registry.get_calendars() # This returns a dictionary >>> for code, calendar_class in calendars.items(): ... print(f"`{code}` is code for {calendar_class.name!r}") `AT` is code for 'Austria' `BE` is code for 'Belgium' `BG` is code for 'Bulgaria' `HR` is code for 'Croatia' `CY` is code for 'Cyprus' `CZ` is code for 'Czech Republic' `EE` is code for 'Estonia' `DK` is code for 'Denmark' `FI` is code for 'Finland' `FR` is code for 'France' ... continued ``` The "private property" `registry.region_registry` is a `dict` object, with the ISO code as a key, and the calendar class as the value. As a "workalendar standard", **every** calendar in the registry has a `name` property (derived from the docstring), so you'd probably be able to build a user-friendly list of available calendars, for a dropdown list, for example. **DEPRECATION WARNING**: As of version 9.0.0, the ``IsoRegistry.items()`` has been renamed into ``IsoRegistry.get_calendars()`` for all your queries in the registry. ## Retrieve a collection of regions If you want the full dictionary of **countries**, you can use the ``get_calendars()`` method. ```python >>> registry.get_calendars() {'AT': , 'BE': , 'BG': , 'KY': , # ... continued } ``` Let's say you'd need only a subset of the ISO registry. For example, France, Switzerland and Canada calendars. You can use the method `get_calendars()` to filter only the calendars you want. ```python >>> registry.get_calendars(['FR', 'CH', 'CA']) {'FR': , 'CH': , 'CA': } ``` Also, if you want those regions **and** their subregions, you can use the `include_subregions` flag: ```python >>> registry.get_calendars(['FR', 'CH', 'CA'], include_subregions=True) {'FR': workalendar.europe.france.France, 'CH': workalendar.europe.switzerland.Switzerland, 'CH-AG': workalendar.europe.switzerland.Aargau, 'CH-AI': workalendar.europe.switzerland.AppenzellInnerrhoden, 'CH-AR': workalendar.europe.switzerland.AppenzellAusserrhoden, 'CH-BE': workalendar.europe.switzerland.Bern, 'CH-BL': workalendar.europe.switzerland.BaselLandschaft, 'CH-BS': workalendar.europe.switzerland.BaselStadt, 'CH-FR': workalendar.europe.switzerland.Fribourg, 'CH-GE': workalendar.europe.switzerland.Geneva, 'CH-GL': workalendar.europe.switzerland.Glarus, 'CH-GR': workalendar.europe.switzerland.Graubunden, 'CH-JU': workalendar.europe.switzerland.Jura, 'CH-LU': workalendar.europe.switzerland.Luzern, 'CH-NE': workalendar.europe.switzerland.Neuchatel, 'CH-NW': workalendar.europe.switzerland.Nidwalden, 'CH-OW': workalendar.europe.switzerland.Obwalden, 'CH-SG': workalendar.europe.switzerland.StGallen, 'CH-SH': workalendar.europe.switzerland.Schaffhausen, 'CH-SO': workalendar.europe.switzerland.Solothurn, 'CH-SZ': workalendar.europe.switzerland.Schwyz, 'CH-TG': workalendar.europe.switzerland.Thurgau, 'CH-TI': workalendar.europe.switzerland.Ticino, 'CH-UR': workalendar.europe.switzerland.Uri, 'CH-VD': workalendar.europe.switzerland.Vaud, 'CH-VS': workalendar.europe.switzerland.Valais, 'CH-ZG': workalendar.europe.switzerland.Zug, 'CH-ZH': workalendar.europe.switzerland.Zurich, 'CA': workalendar.america.canada.Canada, 'CA-ON': workalendar.america.canada.Ontario, 'CA-QC': workalendar.america.canada.Quebec, 'CA-BC': workalendar.america.canada.BritishColumbia, 'CA-AB': workalendar.america.canada.Alberta, 'CA-SK': workalendar.america.canada.Saskatchewan, 'CA-MB': workalendar.america.canada.Manitoba, 'CA-NB': workalendar.america.canada.NewBrunswick, 'CA-NS': workalendar.america.canada.NovaScotia, 'CA-PE': workalendar.america.canada.PrinceEdwardIsland, 'CA-NL': workalendar.america.canada.Newfoundland, 'CA-YT': workalendar.america.canada.Yukon, 'CA-NT': workalendar.america.canada.NorthwestTerritories, 'CA-NU': workalendar.america.canada.Nunavut} ``` *Note*: if any of the codes is unknown, this function won't raise an error. You can also get the full dict of all calendars registered in the ISO Registry with all the subregions using the following function call: ```python >>> registry.get_calendars(include_subregions=True) ``` ## Select only one calendar Let's say that we only know the ISO code for Switzerland (`CH`). If we want to compute holidays for Switzerland in 2018, we can do as follows: ```python >>> CalendarClass = registry.get('CH') >>> calendar = CalendarClass() >>> calendar.holidays(2018) [(datetime.date(2018, 1, 1), 'New year'), (datetime.date(2018, 3, 30), 'Good Friday'), (datetime.date(2018, 4, 1), 'Easter Sunday'), (datetime.date(2018, 4, 2), 'Easter Monday'), (datetime.date(2018, 5, 10), 'Ascension Thursday'), (datetime.date(2018, 5, 20), 'Whit Sunday'), (datetime.date(2018, 5, 21), 'Whit Monday'), (datetime.date(2018, 8, 1), 'National Holiday'), (datetime.date(2018, 12, 25), 'Christmas Day'), (datetime.date(2018, 12, 26), 'Boxing Day')] ``` *Note*: this function would return `None` if the code is unknown. **DEPRECATION WARNING**: As of version 10.0.0, the ``IsoRegistry.get_calendar_class()`` has been renamed into ``IsoRegistry.get()`` to retrieve a single calendar class out of the registry. ## Select only sub-regions As an example, the United States of America, or Australia and others are divided into "sub-regions" (states, provinces, territories, etc). There are usually Federal or State holidays, and variants depending on the region you're targeting. ```python >>> registry.get_subregions('AU') {'AU-ACT': , 'AU-NSW': , 'AU-NT': , 'AU-QLD': , 'AU-SA': , 'AU-TAS': , 'AU-VIC': , 'AU-WA': } ``` *Note*: this function will return an empty `dict` if the code is unknown. [Home](index.md) / [Basic usage](basic.md) / [Advanced usage](advanced.md) / [Class options](class-options.md) / [iCal Export](ical.md) / [Contributing](contributing.md) calendra-7.9.0/mypy.ini000066400000000000000000000002321457013633400150020ustar00rootroot00000000000000[mypy] ignore_missing_imports = True # required to support namespace packages # https://github.com/python/mypy/issues/14057 explicit_package_bases = True calendra-7.9.0/pyproject.toml000066400000000000000000000002131457013633400162160ustar00rootroot00000000000000[build-system] requires = ["setuptools>=56", "setuptools_scm[toml]>=3.4.1"] build-backend = "setuptools.build_meta" [tool.setuptools_scm] calendra-7.9.0/pytest.ini000066400000000000000000000010141457013633400153330ustar00rootroot00000000000000[pytest] norecursedirs=dist build .tox .eggs addopts=--doctest-modules filterwarnings= ## upstream # Ensure ResourceWarnings are emitted default::ResourceWarning # realpython/pytest-mypy#152 ignore:'encoding' argument not specified::pytest_mypy # python/cpython#100750 ignore:'encoding' argument not specified::platform # pypa/build#615 ignore:'encoding' argument not specified::build.env # dateutil/dateutil#1284 ignore:datetime.datetime.utcfromtimestamp:DeprecationWarning:dateutil.tz.tz ## end upstream calendra-7.9.0/ruff.toml000066400000000000000000000006001457013633400151410ustar00rootroot00000000000000[lint] ignore = [ # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", "E111", "E114", "E117", "D206", "D300", "Q000", "Q001", "Q002", "Q003", "COM812", "COM819", "ISC001", "ISC002", ] [format] # Enable preview, required for quote-style = "preserve" preview = true # https://docs.astral.sh/ruff/settings/#format-quote-style quote-style = "preserve" calendra-7.9.0/setup.cfg000066400000000000000000000024441457013633400151330ustar00rootroot00000000000000[metadata] name = calendra author = Jason R. Coombs author_email = jaraco@jaraco.com description = Worldwide holidays and working days helper and toolkit. long_description = file:README.md long_description_content_type = text/markdown url = https://github.com/jaraco/calendra classifiers = Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: MIT License Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only [options] include_package_data = true python_requires = >=3.8 install_requires = python-dateutil lunardate backports.zoneinfo;python_version<"3.9" tzdata;platform_system=="Windows" convertdate pyluach importlib_metadata; python_version < "3.8" more_itertools [options.extras_require] testing = # upstream pytest >= 3.5, !=3.7.3 pytest-checkdocs >= 2.4 pytest-cov # disabled because there are 88 failures # pytest-mypy; \ # workaround for jaraco/skeleton#22 # python_implementation != "PyPy" pytest-enabler >= 2.2 pytest-ruff >= 0.2.1 # local pygments pytest-cov pytest-pep8 pandas jaraco.test >= 3.2.0 freezegun docs = # upstream sphinx >= 3.5 jaraco.packaging >= 9.3 rst.linker >= 1.9 furo sphinx-lint # local astronomy = skyfield skyfield-data tqdm [options.entry_points] calendra-7.9.0/towncrier.toml000066400000000000000000000000541457013633400162160ustar00rootroot00000000000000[tool.towncrier] title_format = "{version}" calendra-7.9.0/tox.ini000066400000000000000000000026321457013633400146240ustar00rootroot00000000000000[testenv] description = perform primary checks (tests, style, types, coverage) allowlist_externals = flake8 py.test pyup_dirs deps = setenv = PYTHONWARNDEFAULTENCODING = 1 commands = pytest {posargs} usedevelop = True extras = testing astronomy [testenv:diffcov] description = run tests and check that diff from main is covered deps = {[testenv]deps} diff-cover commands = pytest {posargs} --cov-report xml diff-cover coverage.xml --compare-branch=origin/main --html-report diffcov.html diff-cover coverage.xml --compare-branch=origin/main --fail-under=100 [testenv:docs] description = build the documentation extras = docs testing changedir = docs commands = python -m sphinx -W --keep-going . {toxinidir}/build/html python -m sphinxlint \ # workaround for sphinx-contrib/sphinx-lint#83 --jobs 1 [testenv:finalize] description = assemble changelog and tag a release skip_install = True deps = towncrier jaraco.develop >= 7.23 pass_env = * commands = python -m jaraco.develop.finalize [testenv:release] description = publish the package to PyPI and GitHub skip_install = True deps = build twine>=3 jaraco.develop>=7.1 pass_env = TWINE_PASSWORD GITHUB_TOKEN setenv = TWINE_USERNAME = {env:TWINE_USERNAME:__token__} commands = python -c "import shutil; shutil.rmtree('dist', ignore_errors=True)" python -m build python -m twine upload dist/* python -m jaraco.develop.create-github-release