Metadata-Version: 2.4
Name: dateling
Version: 1.3.0
Summary: 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
Home-page: https://github.com/nostaljic/dateling
Author: jaypyon
Author-email: scorpion@dgu.ac.kr
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas
Requires-Dist: python-dateutil
Dynamic: author
Dynamic: author-email
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# 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

---

## 📅 DSL Syntax

The general expression format is:

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

### Anchors:

* `today` (system reference date)
* `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=MM` → override month
* `day=DD` → override day

---

## 📊 Examples

| DSL Expression                  | Meaning                               |
| ------------------------------- | ------------------------------------- |
| `{today}` | today's date |
| `{today -1d}` | 1 day before today |
| `{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|
| `{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 |

---

## 🔬 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

```python
from dateling import DatelingResolver

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

You may also set a fixed reference date:

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

---

## 📦 Installation

```bash
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.
