Skip to content

Repository files navigation

Dates and holidays operations 2.0

A robust, fault-tolerant Python library for date calculations in Robotic Process Automation (RPA).

rpa-dates simplifies complex date arithmetic—especially regarding working days and holidays—ensuring your automation bots never crash due to unexpected calendar edge cases or API outages.

License: MIT Python 3.10+ PyPI Build Status uv Code Style: Ruff Checked with Pyrefly Security: Bandit Robocorp RPA Automation ISO 27001 Compliant ISO 8601 Supported 12-Factor Ready SOLID Principles CUPID Principles

Key Features

  • Resilient Holiday Fetching: Uses a "Chain of Responsibility" fallback strategy.

    1. Local Library (0ms latency, works offline).
    2. Nager.Date API (Primary Web API).
    3. OpenHolidays API (Backup Web API).
  • If one fails, the next one takes over automatically.

  • Production-Grade Working Day Logic:

    • Correctly handles year boundaries (e.g., adding 5 working days to Dec 29th).
    • Preserves time components (e.g., 14:30 remains 14:30).
    • Supports positive and negative offsets.
  • RPA-Friendly: Designed to handle string, date, and datetime inputs interchangeably.

  • Fiscal Year Support: Built-in utilities for fiscal calendars.

Installation

Install using uv (recommended) or pip:

uv add rpa-dates
# OR
pip install rpa-dates

Quick Start

Basic Date Operations

The DateService accepts strings, dates, or datetimes and normalizes them automatically.

from rpa_dates import DateService

ds = DateService()

# Normalizes inputs automatically
dt = ds.normalize("11.02.2025")  # Returns datetime object

# Easy offsets
future_date = ds.offset("01.01.2025", days=10, months=1)
print(future_date)  # 11.02.2025

Working with Business Days

Calculate deadlines accurately by skipping weekends and public holidays.

# Calculate +5 working days from a Friday
# Skips Sat, Sun, and any public holidays found for the country (e.g., 'US')
deadline = ds.working_day_offset(5, "2025-07-03", country_code="US")

print(deadline)
# If July 4th is a holiday, this correctly skips it!

Finding the Nth Working Day

Perfect for "Report is due on the 3rd working day of the month" scenarios.

# Get the 3rd working day of January 2025 in Poland (PL)
report_date = ds.nth_working_day_of_month(3, "2025-01-01", country_code="PL")

print(report_date)
# 2025-01-01 is New Year (Holiday) -> Skip
# 2025-01-02 (Thu) -> 1st WD
# 2025-01-03 (Fri) -> 2nd WD
# 2025-01-04 (Sat) -> Skip
# 2025-01-05 (Sun) -> Skip
# 2025-01-06 (Mon) is Epiphany (Holiday) -> Skip
# 2025-01-07 (Tue) -> 3rd WD (Result)

Configuration

You can customize the service behavior using DateConfig.

from rpa_dates import DateService, DateConfig

config = DateConfig(
    default_input_format='%Y-%m-%d',
    fiscal_year_start_month=10,  # e.g., US Government fiscal year
    api_timeout_seconds=5
)

ds = DateService(config=config)

Architecture: The Provider Fallback

The library guarantees high availability for holiday data using a multi-provider strategy.

  • LocalPythonHolidayProvider: Checks the local holidays Python package. Fast and offline.
  • NagerDateV3Provider: Queries date.nager.at.
  • NagerDateV4Provider: Queries the newer V4 API.
  • OpenHolidaysProvider: Queries openholidaysapi.org.

You don't need to configure this; it happens automatically inside ProviderFactory.

Contributing

I use uv for dependency management.

  1. Clone the repo:

    git clone [https://github.com/21010/rpa-dates.git](https://github.com/21010/rpa-dates.git)
    cd rpa-dates
  2. Install dependencies:

    uv sync
  3. Run Tests:

    uv run pytest

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A Python utility for common date/time operations, including business days and public holidays. Ideal for RPA and scripting.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages