Skip to main content

dateling provides a normalized formal language and grammar for handling relative time expressions. It includes a DSL (domain-specific language) to represent time anchors, offsets, and modifiers, along with a robust parser and resolver to evaluate these expressions into concrete dates. The name 'dateling' comes from combining 'date' and 'handling', reflecting its purpose of handling complex date computations

Project description

dateling

🕰 dateling — A Time Expression DSL and parser for deterministic date calculations.

dateling provides a normalized formal language (DSL) to represent and resolve date calculations using structured expressions.
Instead of parsing ambiguous natural language, it offers a precise syntax to express relative and absolute dates, compute date ranges, and perform robust date arithmetic.

The name dateling comes from combining date and handling.


🚀 Why dateling?

Most existing packages like dateparser or parsedatetime try to interpret free-text natural language into dates.
In contrast, dateling takes a strict, declarative, and composable approach, offering:

  • ✅ Predictable & reproducible date evaluation
  • ✅ Fully composable date expressions
  • ✅ Explicit syntax without ambiguity
  • ✅ Ideal for any system requiring controlled time range calculations
  • ✅ No natural language processing — purely deterministic time logic

📦 What's New in v1.2 & v1.3

✅ v1.2 Updates:

  • Added ${} support as an alternative bracket style to {}.
  • Added new anchor keywords:
    • first_date_of_this_month — resolves to the first day of the current month.
    • monday_of_this_week — resolves to the Monday of the current week.

✅ v1.3 Updates:

  • Added month=nearest_month modifier.
    • Similar to year=nearest_year, but applies nearest-month logic.
    • If the resolved date falls into the future, fallback to previous month (and adjust year if necessary).
  • Further improved composability of partial expressions (ex: "11일의 주가 알려줘" → {today | year=nearest_year, month=nearest_month, day=11}).

✅ v1.3.1 Updates:

  • Added new anchor keywords:
    • first_date_of_this_year — resolves to the first day of the current year.

✅ v1.3.2 Updates:

  • Supports for blank after (+/-) sign:
    • now supports for {today + 1d}

📅 DSL Syntax

The general expression format is:

{anchor [+/- offset] | [modifiers]}

Anchors:

  • today (system reference date)
  • first_date_of_this_year
  • first_date_of_this_month
  • monday_of_this_week
  • YYYYMMDD (e.g. 20250101)
  • YYYY-MM-DD (e.g. 2025-01-01)

Offsets:

  • Days: +Nd, -Nd
  • Months: +Nm, -Nm
  • Years: +Ny, -Ny

Modifiers:

  • year_start → resolves to start of year
  • year_end → resolves to end of year
  • year=nearest_year → use anchor year, fallback to previous year if resulting date is in the future
  • year=YYYY → explicitly set year
  • month=nearest_month → anchor month, fallback to previous month if resulting date is in the future
  • month=MM → override month
  • day=DD → override day

📊 Examples

DSL Expression Meaning
{today} today's date
${today} today's date
{today -1d} 1 day before today
${today -1d} 1 day before today
{today -1y | year_start} start of year, 1 year ago
${today -1y | year_start} start of year, 1 year ago
{2025-01-01 +30y | year_end} year-end of 30 years after Jan 1, 2025
${2025-01-01 +30y | year_end} year-end of 30 years after Jan 1, 2025
{today | year=nearest_year, month=03, day=10} resolves to March 10 of anchor year (or previous year if future)
${today | year=nearest_year, month=03, day=10} resolves to March 10 of anchor year (or previous year if future)
{year=2023, month=05, day=15} absolute date
${year=2023, month=05, day=15} absolute date

🔬 Evaluation Example (Reference date: 2025-06-11)

DSL Output
{today} 2025-06-11
{today -1d} 2025-06-10
{today -365d | year=nearest_year} 2024-06-11
{today -3y} 2022-06-11
{today | year_start} 2025-01-01
{today | year_end} 2025-12-31
{today -1y | year_start} 2024-01-01
{today -1y | year_end} 2024-12-31
{today | year=nearest_year, month=06, day=10} 2025-06-10
{today -1y | year=nearest_year, month=03, day=10} 2024-03-10
{today | year=2024, month=06, day=10} 2024-06-10
{year=2022, month=05, day=15} 2022-05-15
2025-01-01 2025-01-01
20250101 2025-01-01
{1000-01-01 +30y | year_end} 1030-12-31
{today -36m} 2022-06-11

⚙ Usage

from dateling import DatelingResolver

resolver = DatelingResolver()
date = resolver.resolve("{today -1y | year_start}")
print(date)

You may also set a fixed reference date:

resolver = DatelingResolver(reference_date="2025-06-11")
date = resolver.resolve("{today -3y | year_end}")
print(date)

📦 Installation

pip install dateling

(Once released to PyPI)


🔧 Design Philosophy

  • 🧮 Formal expression language for time calculation
  • 🔎 Fully deterministic, reproducible, and testable
  • 🏷 No AI or natural language guessing
  • 📈 Applicable across scheduling, reporting, ETL, search systems, financial applications, etc.

📄 License

MIT License


🔗 Related Alternatives

Package Approach Difference from dateling
dateparser Natural language parsing No DSL, free-text interpretation
parsedatetime Human language parsing No formal syntax, heuristic parsing
textX Generic DSL builder Requires custom DSL grammar creation
dateling DSL-based date expression language Strict syntax for controlled date calculations

🧭 dateling: When you want to write date calculations, not guess them.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dateling-1.3.2.tar.gz (5.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dateling-1.3.2-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file dateling-1.3.2.tar.gz.

File metadata

  • Download URL: dateling-1.3.2.tar.gz
  • Upload date:
  • Size: 5.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for dateling-1.3.2.tar.gz
Algorithm Hash digest
SHA256 2e366b85aa43a66e74c5a7ddfb8a7a89a184a6a4d84e739c8fba5c391877380e
MD5 a2e405a51849b86a3957676a650211d4
BLAKE2b-256 d0e2fef9780030b8bc0fece02a4b1ceb45d7966a3972b46b89322fb0835ad8ed

See more details on using hashes here.

File details

Details for the file dateling-1.3.2-py3-none-any.whl.

File metadata

  • Download URL: dateling-1.3.2-py3-none-any.whl
  • Upload date:
  • Size: 5.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for dateling-1.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 648453ab44b786aad16aad76e9d188fe2631825800c608022f78c65611636618
MD5 35bcf9a130ea0b8919846781114a7276
BLAKE2b-256 ec46c584dd5d3340e44ded742ab4aabda0c7ff6a66f98887fd9b4c6ac9cfdd26

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page