Overview of Workalendar capabilities
masterWorkalendar is a Python module designed for calendar management. It provides classes to:
- Handle various calendars.
- List legal and religious holidays.
- Perform computations related to working days.
repository·master·Indexed 21 days ago
https://github.com/workalendar/workalendarA Python module for handling global calendars, listing legal and religious holidays, and performing working-day-related computations. It supports various regions including Europe, America, Asia, Oceania, and Africa. Key features include calculating working days between dates, finding the nth weekday of a month, and providing tools for implementing custom calendar classes with support for astronomical computations.
Workalendar is a Python module designed for calendar management. It provides classes to:
While custom options provide flexibility, follow these guidelines to avoid complexity:
ERR_TOO_MANY_OPTIONS, where the logic becomes hard to maintain and cover with tests.Calendar options are not limited to boolean flags. You can use any Python type to drive complex holiday logic. Common patterns include:
day_of_the_founder_label='Custom Name') or specifying a region.number_of_days_after_new_year=3).This approach is preferred over creating multiple derivative classes when the number of possible combinations of rules becomes too large to manage via inheritance.
To minimize computation time, equinoxes and solar terms are precomputed for 30 years before and after the current year. If you modify astronomical data or add timezones to it, you must:
create-astronomical-data script to update the data files..json.gz files if adding a timezone to the astronomical data.Workalendar accepts both datetime.date and datetime.datetime objects from the Python standard library.
Important Notes:
UnsupportedDateType error.datetime.date object even if a datetime.datetime was provided as input.datetime.datetime instead of a datetime.date), use the keep_datetime=True argument in methods like add_working_days.from datetime import date, datetime
from workalendar.europe import France
cal = France()
# Default behavior: returns datetime.date
res = cal.add_working_days(datetime(2012, 12, 23, 14, 0, 39), 5)
# datetime.date(2012, 12, 31)
# Using keep_datetime=True to return datetime.datetime
res_dt = cal.add_working_days(datetime(2012, 12, 23, 14, 0, 39), 5, keep_datetime=True)
# datetime.datetime(2012, 12, 31, 14, 0, 39)To contribute to Workalendar, you should set up a local development environment using virtualenv or virtualenvwrapper. This ensures you have the necessary dependencies installed for testing and development.
WORKALENDAR.pip install -e ./ from the root of the cloned repository.mkvirtualenv WORKALENDAR
pip install -e ./Since v13.0.0, you can define custom options for a calendar class by overriding the __init__ method. This allows you to pass arguments (flags, strings, numbers, or objects) to the constructor to dynamically change holiday behavior based on runtime context (e.g., employee location, region, or specific years).
To implement this:
__init__ method.super().__init__(**kwargs) to ensure the base class is initialized correctly.self.option_name).get_variable_days to conditionally add holidays.@iso_register('ZK')
class Zhraa(WesternCalendar):
def __init__(self, include_january_2nd=False, **kwargs):
super().__init__(**kwargs)
self.include_january_2nd = include_january_2nd
def get_variable_days(self, year):
days = super().get_variable_days(year)
# ... add other days ...
if self.include_january_2nd:
days.append((date(year, 1, 2), "January 2nd"))
return days
# Usage in business logic
calendar = Zhraa(include_january_2nd=True)All contributions must follow PEP8 guidelines and pass specific linting and compatibility checks:
tox -e flake8 to check for style violations.pyupgrade fails, run tox -r pyupgrade to automatically modify your code to meet standards (note: verify this doesn't break flake8 compliance).workalendar/tests/ directory (e.g., inheriting from GenericCalendarTest) to verify holiday computations.# Check PEP8 compliance
tox -e flake8
# Automatically fix pyupgrade issues
tox -r pyupgrade
# Install tox for running tests
pip install toxWorkalendar is built around configuration variables and generic methods. To add a new calendar:
WesternCalendar for Gregorian-based calendars or other existing Mixins/Calendars.FIXED_HOLIDAYS tuple from the base class.include_labour_day or include_easter_monday to activate standard holidays.get_variable_days(self, year) method. This method should call super().get_variable_days(year) and return a list of tuples containing (date_object, 'Label').@iso_register('CODE') decorator from ..registry_tools to make it queryable via the global registry.from ..core import WesternCalendar
from ..registry_tools import iso_register
@iso_register('ZK')
class Zhraa(WesternCalendar):
"""Kingdom of Zhraa"""
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)
# Example: Adding a day based on a specific weekday rule
days.append(
(Zhraa.get_nth_weekday_in_month(year, 6, MON), 'Day of the Founder'),
)
return daysYou can install Workalendar using either pip or conda.
Using pip:
pip install workalendarUsing conda:
conda install -c conda-forge workalendarpip install workalendarSome calendars (like certain Asian calendars) require astronomical computations for equinoxes or solar terms.
By default, Workalendar provides pre-computed values for the range 1991 to 2051. If you prefer to compute these yourself using astronomical libraries, install the [astronomy] extra dependency:
pip install workalendar[astronomy]Note on performance: If you have skyfield and skyfield-data installed, Workalendar will use them for computation. To switch back to the faster pre-computed cache, you must uninstall those packages.
pip install workalendar[astronomy]Workalendar provides several levels of usage guidance depending on your needs: