# Dates with Jev: extract parts as Choices, resolve in code

> TypeSafe date-extraction cookbook: 7 Choice questions read a date's parts off the text, code resolves absolute and relative dates with confidence gating — 6/6 on the demo set.

*Source: https://velstech.net/jev-date-extraction.hi (Hindi translation of https://velstech.net/jev-date-extraction) · Updated: 2026-09-20*

*Markdown version. [Read the interactive guide](https://velstech.net/jev-date-extraction.hi). English Markdown: https://velstech.net/jev-date-extraction.md.*

---

तारीखें [Jev 1.13 jaggedness](https://velstech.net/jev-1-13-jaggedness.hi) का textbook case हैं:
model "August 14" को text की तरह पढ़ता है, ordered quantity की तरह नहीं, इसलिए कौन सी date पहले
आती है या दो dates में कितना अंतर है – गलत हो जाता है; mixed formats, "next Thursday" और quarters
जैसी domain boundaries के साथ और खराब। TypeSafe का
[date-extraction cookbook](https://docs.typesafe.ai/cookbooks/date_extraction_cookbook)
वह fix दिखाता है जो टिकता है: **सात Choice सवाल एक call में तारीख का shape और
parts text से पढ़ते हैं; साधारण code जवाबों को असली date में बदलता है**,
relative dates के लिए आज से गिनकर, कमज़ोर reads को इंसान के पास भेजने वाले confidence gate के साथ।
यह guide recipe का सारांश है, key code shape के साथ।

अंत में एक function मिलता है, `extract_date(document, role)`: document और "the deadline
to return the form" जैसा phrase दें, date + confidence पाएँ – या flag कि ऐसी कोई date है ही नहीं,
या कोई व्यक्ति देखे।

## Pattern: parts के लिए Choices, calendar के लिए code

तारीख का हर part छोटा closed set है – बारह महीने, इकतीस दिन, bounded साल – इसलिए extraction
free-form parsing के बजाय enumerated options पर `Choice` बन जाता है, explicit "not
stated" escape के साथ ताकि गुम part guess करने के बजाय report हो। सात सवाल:

- mode – date कैसे लिखी है: absolute (महीने का नाम),
relative (today, tomorrow, day after, named weekday), या none
(document में यह date है ही नहीं)।

- month, day, year – absolute parts। Year list 1900–2050,
दो escapes के साथ: none (code साल मान लेता है) और out_of_range
(flag होता है, guess कभी नहीं)।

- day_anchor – today / tomorrow / day_after / weekday।

- weekday + week_offset – कौन सा weekday, कौन सा हफ़्ता:
current ("this Thursday"), next ("next Thursday"), या bare
("Thursday" = आज से अगला occurrence)।

Code सिर्फ वही pieces पढ़ता है जो `mode` माँगे, `date` assemble करता है, और
इस्तेमाल हुए parts में **सबसे कम confidence** report करता है – ताकि एक कमज़ोर part
पूरी date को review में भेज दे। 0.60 से नीचे कुछ भी, या जो code assemble ही न कर सके, इंसान के पास
जाता है; बाकी सीधे through।

## Code में सवाल

```
def date_questions(role: str) -> dict[str, Choice]:
    """Seven typed choices that read a date's shape and parts off the text -- no math."""
    absent = "The document does not state this, or it is not this kind of date."
    return {
        "mode": Choice(
            instructions=(
                f"How is {role} written? 'absolute' = a calendar date naming a month; "
                "'relative' = relative to today; 'none' = the document does not state it."
            ),
            criteria={"absolute": None, "relative": None, "none": None},
        ),
        "month": Choice(
            instructions=f"If {role} is an absolute calendar date, which month is it in?",
            criteria={m: None for m in MONTHS} | {"none": absent},
        ),
        "day": Choice(
            instructions=f"If {role} is an absolute calendar date, which day (1-31)?",
            criteria={str(d): None for d in range(1, 32)} | {"none": absent},
        ),
        "year": Choice(
            instructions=(
                f"If {role} is an absolute calendar date, which year? 'none' if unstated "
                "(code infers it), 'out_of_range' if stated but off the list."
            ),
            criteria={str(y): None for y in YEAR_WINDOW}
            | {"out_of_range": "Stated but outside the listed range.",
               "none": "No year is stated."},
        ),
        "day_anchor": Choice(
            instructions=f"If {role} is relative to today, which day is it?",
            criteria={"today": None, "tomorrow": None, "day_after": None,
                      "weekday": None, "none": absent},
        ),
        "weekday": Choice(
            instructions=f"If {role} names a day of the week, which one?",
            criteria={w: None for w in WEEKDAYS} | {"none": absent},
        ),
        "week_offset": Choice(
            instructions=f"If {role} names a weekday, which week?",
            criteria={"current": None, "next": None, "none": absent},
        ),
    }
```

## Code में resolve करें

Assemble step जानबूझकर boring calendar math है: गुम साल भरें (current year, सिर्फ तभी next जब
date एक महीने से ज़्यादा पुरानी हो), stated convention से named weekday को date में बदलें,
February 30 जैसी impossible dates को inconsistent reads मानकर reject करें। Year inference और
weekday resolution दोनों pinned `TODAY` से गिनते हैं ताकि relative dates हर run में
reproduce हों:

```
def extract_date(document: str, role: str) -> dict:
    return assemble(read_parts(document, role))  # one TypeSafe call, then pure code
```

## Demo set पर नतीजे

चार छोटे documents पर छह सवाल (contract, form, survey, review notice), fixed Thursday के हिसाब
से resolve। छह के छह सही:

| सवाल | Expected | Got | Conf | Flags |
| --- | --- | --- | --- | --- |
| Agreement कब effective | 2025-01-01 | 2025-01-01 | 0.97 | – |
| Agreement कब expires | 2027-12-31 | 2027-12-31 | 0.91 | – |
| Form return की deadline | 2026-08-14 | 2026-08-14 | 0.95 | – |
| Kickoff call की date | none | none | 0.46 | review |
| Survey close ("today") | 2026-07-30 | 2026-07-30 | 0.94 | – |
| Design review ("next Thursday") | 2026-08-06 | 2026-08-06 | 0.92 | – |

दिलचस्प row kickoff call है – वह date form में है ही नहीं। Model फिर भी `absolute`
shape देता है बिना month के, इसलिए date खाली आती है 0.46 confidence पर, hallucinate होने के बजाय
इंसान के लिए flagged। पाँच auto-accept, एक human review: यही पूरा operating point है।

## Bottom line

Jev से calendar math कभी न करवाएँ – text में कौन से boxes tick हैं यह पूछें, फिर math खुद करें।
Closed sets पर Choices + explicit "not stated" options + weakest-link confidence – dates से कहीं
आगे reusable shape है। Full source:
[TypeSafe का date-extraction cookbook](https://docs.typesafe.ai/cookbooks/date_extraction_cookbook);
dates jagged क्यों हैं, इसकी background
[Jev 1.13 jaggedness guide](https://velstech.net/jev-1-13-jaggedness.hi) में।

---

*VelsTech – https://velstech.net/jev-date-extraction.hi.md*
