DTRExp — Date-Time Range & Recurrence Expression: parsing, validation and coverage evaluation (spec draft 2.8)
Project description
dtrexp-py
Python implementation of DTRExp (read: "DTR Expression") — a compact string expression for date-time ranges and recurrence, evaluated by coverage rather than enumeration.
T0900:1800 E1:5 Mon–Fri, 09:00–18:00
E7#-1 M4 last Sunday of April, every year
20200106/10D every 10 days from 2020-01-06 (cron can't say this)
M!7 every month except July
Scope: parsing, validation and coverage evaluation — the spec's core interface. Rendering, description and RRULE export are out of scope; the reference implementation has them.
Install
pip install dtrexp
Python 3.11+, stdlib only (zoneinfo for IANA zones).
Usage
from datetime import datetime, timezone
import dtrexp
dtr = dtrexp.parse("T0900:1800 E1:5") # business hours, Mon–Fri
dtr.covers(datetime(2026, 7, 7, 10, 0, tzinfo=timezone.utc))
# —> True (UTC — the default)
dtr.covers(datetime(2026, 7, 7, 7, 30, tzinfo=timezone.utc), tz="Europe/Berlin")
# —> True (09:30 Berlin local time)
Note that you parse once (at write/config time) and evaluate many; Expression objects are immutable, and covers is a single calendar-field extraction followed by integer comparisons (no occurrence iteration). The zone is an evaluation parameter, never part of the expression. covers also accepts an ISO 8601 string for the instant.
Errors and Warnings
Both carry a position; the 0-based character offset into the source:
dtrexp.parse("Y*/3")
# raises DTRExpSyntaxError: "anchorless stride — an explicit start is required (at 1)"
# error.position —> 1
res = dtrexp.validate("D30 M2") # never raises
res.valid # True — it parses
res.warnings # (DTRExpWarning(message="unsatisfiable …", position=0),)
parse(text)raisesDTRExpSyntaxError(aValueError) on invalid input; position points at the offending character and is appended to the rendered message.validate(text)never raises; typo-shaped input comes back as data. Returns a frozenValidationResultwith validbool, errors (parsing stops at the first syntax error, so at most one) and warnings.- Warnings are the spec's §9.1 unsatisfiability lint: expressions that parse but can never match. They are
DTRExpWarningobjects (messagestr, positionint | None);str(warning)is the message.Expression.warningsandvalidate(text).warningscarry the same content.
Conformance & Quality
- The test suite is driven by the shared
vectors.jsonfrom the spec repo (draft 2.8): every coverage, rejection, warning and quiet vector, including the calendar traps (Feb 29 across 2000/2024/2100,W53existence, DST gap/overlap inEurope/Berlin). See VECTORS.md for how the suite works. - 100% line + branch coverage, enforced (
uv run poe cover); mutation-tested with mutmut (uv run poe mutation). - Zero dependencies.
Related Projects
- dtrexp (spec): the DTRExp specification (grammar, semantics, conformance vectors) this package implements.
- dtrexp-js: the reference implementation; adds
intersect,next,describe,toRRuleand canonicalization. - dtrexp-go · dtrexp-swift · dtrexp-rs · dtrexp-java: the other ports; same core interface.
- dtrexp-wasm: the Rust core compiled to WebAssembly for JS hosts.
License
© 2026, Onur Yıldırım. MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dtrexp-1.0.0.tar.gz.
File metadata
- Download URL: dtrexp-1.0.0.tar.gz
- Upload date:
- Size: 71.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a748d6f0a5dcce1c09c8a4feabadb5816067d869e580be3bc6401bb7d7895fba
|
|
| MD5 |
2d537c8fe5671ee18f557a183168d0ff
|
|
| BLAKE2b-256 |
1911898ab623a13377620cff9654a7b1f4601fa0de3319af7f2838c93bc68213
|
File details
Details for the file dtrexp-1.0.0-py3-none-any.whl.
File metadata
- Download URL: dtrexp-1.0.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7980af84aad40fdeba44d9a5b930bce1f9e616f102297e867897dd0ff688ff1d
|
|
| MD5 |
7aeaf057b8ef57b23dfdc82293e68bde
|
|
| BLAKE2b-256 |
046f86192e6106173cd5c737926b2ecfbed6a647640001c9dcf52d9a2c636122
|