whenparse 0.1.0

Parse natural-language dates and times (English + Russian) into jiff types.
Documentation
  • Coverage
  • 12.5%
    3 out of 24 items documented1 out of 8 items with examples
  • Size
  • Source code size: 57.82 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 513.3 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 5s Average build duration of successful builds.
  • all releases: 5s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • icedracon

whenparse

Parse natural-language dates and times — in English and Russian — into jiff types. One direct dependency, no regex, deterministic.

whenparse turns strings like next friday 8pm, через 2 недели, 15 March 2026, Q3 2025, or 2ч30м into a typed When: a date, a zoned datetime, a range, or a duration.

Why

  • Explicit anchor. Every parse takes a now: &Zoned you supply, so results are deterministic and testable — no hidden clock.
  • Bilingual. English and Russian share one grammar; you get both without a flag.
  • Ranges are first-class. next week, March, and Q3 resolve to a real [start, end) range instead of a lossy point.
  • Small. One direct dependency (jiff). Hand-rolled scanner and grammar, no regex.

Install

[dependencies]
whenparse = "0.1"
jiff = "0.2"

Usage

use jiff::Zoned;
use whenparse::{parse, parse_with, Dialect, Options, When};

let now = Zoned::now();

// Default options: automatic language, international date order.
if let Ok(When::DateTime(z)) = parse_with("next friday 8pm", &now) {
    println!("{z}");
}

// Russian, ranges, and durations go through the same call.
assert!(matches!(parse_with("через 2 недели", &now), Ok(When::Date(_))));
assert!(matches!(parse_with("Q3 2025", &now), Ok(When::Range { .. })));
assert!(matches!(parse_with("2ч30м", &now), Ok(When::Duration(_))));

// Tune the dialect (US month/day order and "next Friday" semantics).
let opts = Options { dialect: Dialect::Us, ..Options::default() };
let _ = parse("3/15/2026", &now, opts); // -> 2026-03-15

Output

pub enum When {
    Date(jiff::civil::Date),
    DateTime(jiff::Zoned),
    Range { start: jiff::Zoned, end: jiff::Zoned },
    Duration(jiff::Span),
}

What it understands

Class English Russian
Named days today, tomorrow, yesterday сегодня, завтра, послезавтра
Offsets in 3 days, 2 weeks ago, in an hour через 3 дня, неделю назад, через час
Weekdays next friday, last monday, this thursday в следующую пятницу, в прошлый вторник
Periods → Range this / next / last week | month | year на следующей неделе, в этом месяце
Absolute 15 March 2026, March 15, 3/15/2026, 15.03.2026 15 марта 2026, 15.03.2026
Months / quarters → Range March, Q3, Q3 2025 март
Clock 8pm, 8:30, noon, at 8 в 17:00, в 8 вечера, в полдень
Combined tomorrow at 5pm, next friday 8pm завтра в 17:00
Durations → Duration 3 hours 20 minutes, 2h30m 3 часа 20 минут, 2ч30м

ISO 8601 input (2026-03-15, 2026-03-15T14:30:00[America/New_York]) passes straight through to jiff.

Options

  • lang: Auto (default), En, or Ru.
  • dialect: Intl (default; day/month/year) or Us (month/day/year; next Friday means the coming Friday). Ambiguous numeric dates auto-correct when only one ordering is valid.
  • week_start: the first day of the week for period ranges (default Monday).

Not in scope (v0.1)

Time zones by name or abbreviation, recurrence (every monday), holidays, and spelled-out fractions (half an hour). ISO datetimes are delegated to jiff.

License

Licensed under either of MIT or Apache-2.0 at your option.