python-dateutil-rs
A high-performance Rust-backed port of python-dateutil (v2.9.0).
Status: All core modules (easter, relativedelta, parser, rrule, tz) are rewritten in Rust via PyO3/maturin. The optimized
dateutil-core+dateutil-pyarchitecture delivers 2x-897x speedups over python-dateutil.
Features
- Drop-in replacement for
python-dateutil— same API, same behavior - Rust-accelerated: easter, relativedelta, parser (
parse/isoparse), rrule, tz, weekday - Optimized core: zero-copy parser, PHF lookup tables, bitflag filters, buffer-reusing rrule
- Comprehensive test suite inherited from the original project
- Benchmark infrastructure for side-by-side performance comparison
- Python 3.10-3.14 supported on Linux and macOS
Installation
Usage
# Parse date strings (zero-copy tokenizer)
=
# ISO-8601 strict parsing
=
# Relative deltas
= +
# Recurrence rules (buffer-reusing iterator)
=
=
= # also iterable
= # indexing
= # slicing
= # total occurrences
in # membership test
# Timezones
=
=
# Easter
=
Development
Prerequisites
- Python 3.10+
- Rust toolchain
- uv (recommended) or pip
Setup
Building
# Build the native extension
# Development build (faster compilation)
Running Tests
# Run the test suite
# Run with coverage
# Run Rust tests
Linting
Benchmarks
Benchmarks compare the original python-dateutil (PyPI) and the Rust extension (dateutil_rs) using pytest-benchmark.
Summary (vs python-dateutil)
| Module | Speedup |
|---|---|
| Parser (parse) | 19.5x-36.0x |
| Parser (isoparse) | 13.0x-38.4x |
| RRule | 5.9x-63.7x |
| Timezone | 1.0x-896.7x |
| RelativeDelta | 2.0x-28.1x |
| Easter | 5.0x-7.3x |
Measured on Apple Silicon (M-series), Python 3.13, release build. Full results: benchmarks/RESULTS.md
# Install the original python-dateutil for comparison
# Run benchmarks
# Run and save results as JSON
Project Structure
dateutil-rs/
├── Cargo.toml # Workspace root
├── pyproject.toml # Python project config (maturin)
├── crates/
│ ├── dateutil-core/ # Pure Rust optimized core (crates.io)
│ │ └── src/
│ │ ├── lib.rs # Crate root, public API
│ │ ├── common.rs # Weekday (MO-SU with N-th occurrence)
│ │ ├── easter.rs # Easter date calculations
│ │ ├── error.rs # Shared error types
│ │ ├── relativedelta.rs
│ │ ├── parser.rs # parse() entry point
│ │ ├── parser/ # tokenizer, parserinfo, isoparser
│ │ ├── rrule.rs # RRule entry point
│ │ ├── rrule/ # iter, parse (rrulestr), set
│ │ └── tz/ # tzutc, tzoffset, tzfile, tzlocal
│ └── dateutil-py/ # PyO3 binding layer → PyPI package
│ └── src/
│ ├── lib.rs # Module registration
│ ├── py.rs # Binding root + #[pymodule]
│ └── py/ # Per-module bindings (common, conv, easter, parser, relativedelta, rrule, tz)
├── python/dateutil_rs/ # Python package (maturin mixed layout)
│ ├── __init__.py # Re-exports from Rust native module
│ ├── _native.pyi # Type stubs for native module
│ ├── py.typed # PEP 561 marker
│ └── parser.py # parserinfo (Python subclass support)
├── tests/ # Python test suite
├── benchmarks/ # pytest-benchmark comparisons
├── .github/workflows/ # CI (ci.yml, publish.yml)
├── Makefile
└── LICENSE
Crate Roles
| Crate | Purpose | PyO3 | Publish To |
|---|---|---|---|
dateutil-core |
Pure Rust optimized core | No | crates.io |
dateutil-py |
PyO3 binding layer | Yes | PyPI (python-dateutil-rs) |
Implementation Status
| Module | Status | Notes |
|---|---|---|
| common (Weekday) | ✅ | MO-SU constants with N-th occurrence |
| easter | ✅ | 5.0x-7.3x faster, 3 calendar methods |
| relativedelta | ✅ | 2.0x-28.1x faster |
| parser (parse) | ✅ | 19.5x-36.0x faster, zero-copy tokenizer, PHF lookups |
| parser (isoparse) | ✅ | 13.0x-38.4x faster |
| parser (parserinfo) | ✅ | Customizable via Python subclass |
| rrule / rruleset | ✅ | 5.9x-63.7x faster, bitflag filters, buffer reuse |
| rrulestr | ✅ | RFC 5545 string parsing |
| tz (tzutc, tzoffset, tzfile, tzlocal) | ✅ | 1.0x-896.7x faster |
| tz utilities (gettz, datetime_exists, etc.) | ✅ | gettz with caching |
Roadmap
Python-only phase — Pure Python port with full test coverage✅Rust core + PyO3 bindings — easter, relativedelta, parser, weekday✅Rust rrule — Rewrite recurrence rules in Rust✅Rust tz — Rewrite timezone support in Rust✅Optimized core — zero-copy parser, buffer-reusing rrule, consolidated architecture✅- Release — Publish dateutil-core to crates.io and python-dateutil-rs 1.0 to PyPI