dateparser

A Rust library that parses dates from dozens of common string formats into chrono UTC datetimes with no configuration.

Library
Cargo
v0.3.1
52stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity8
Maintenance20
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture78
Code Quality68
Innovation72
Learning Curve55

dateparser is a lightweight Rust crate for turning free-form date and time strings into chrono::DateTime<Utc> values without requiring the caller to specify a format string up front. It recognizes a wide range of commonly seen formats out of the box — Unix timestamps (seconds, milliseconds, nanoseconds), RFC3339 and RFC2822, Postgres-style timestamps, slash/dot/hyphen-separated dates, MySQL log timestamps, and even Chinese-language date strings — by chaining regex-guarded format detectors until one matches.

The crate exposes three entry points: parse() for the common case (assumes the system local timezone when none is present in the string), parse_with_timezone() for supplying a custom default timezone, and parse_with() for also supplying a default time-of-day. A DateTimeUtc newtype implements std::str::FromStr so date strings can be parsed idiomatically with Rust’s own .parse::<T>() method. The workspace also ships belt, a small CLI built on top of the crate that displays a given date across multiple named time zones, doubling as a real-world usage example.

What You Get

  • Broad format coverage - accepts Unix timestamps, RFC3339/RFC2822, Postgres timestamps, slash/dot/hyphen date formats, MySQL log timestamps, and Chinese-language dates without any per-call configuration.
  • Three parsing entry points - parse() for local-timezone defaults, parse_with_timezone() to supply a custom fallback timezone, and parse_with() to also supply a default time-of-day.
  • Idiomatic FromStr support - the DateTimeUtc wrapper type lets you call "...".parse::<DateTimeUtc>() instead of a crate-specific function.
  • WASM support - an optional wasm feature swaps the native regex crate for a js_sys::RegExp-backed implementation so the same parsing logic runs in browser targets.
  • A working CLI example - the bundled belt binary parses a date string and prints it across several named time zones, showing the crate used end-to-end.

Common Use Cases

  • Log ingestion pipelines - normalizing timestamps that appear in inconsistent formats across different log sources into a single UTC value.
  • API and webhook payload parsing - accepting date strings from third-party services without knowing their exact format ahead of time.
  • CLI and user-input tools - letting a human type a date in whatever format is natural to them and getting back a normalized DateTime<Utc>.
  • Data import/ETL scripts - parsing date columns from CSVs or scraped data where the source format isn’t guaranteed to be consistent.

Under The Hood

Architecture The crate is a single library within a two-member Cargo workspace (dateparser library plus the belt CLI). Its public surface (lib.rs) exposes parse, parse_with_timezone, parse_with, and the DateTimeUtc newtype; the actual work happens in datetime.rs, where a Parse<'z, Tz2> struct chains roughly a dozen format-family methods (unix_timestamp, rfc2822, ymd_family, hms_family, month_ymd, month_mdy_family, month_dmy_family, slash_mdy_family, hyphen_mdy_family, slash_ymd_family, dot_mdy_or_ymd, mysql_log_timestamp, chinese_ymd_family) via .or_else() short-circuiting, each guarded by a coarse regex prefilter so the more specific per-format regexes only run once the input’s rough shape is plausible. timezone.rs is a small, separate module that resolves abbreviation strings (PST, PDT, UTC, GMT, etc.) and numeric offsets into chrono::FixedOffset. A new_regex! macro compiles each pattern once into a thread_local! static, and a RegexEx trait abstracts over native regex::Regex versus a js_sys::RegExp-backed implementation behind a wasm feature flag, so the same call sites work on both native and WASM targets. There’s no mutable state beyond the Parse struct’s timezone/default-time fields — everything is a pure string-to-DateTime<Utc> transformation.

Tech Stack Rust 2021 edition, organized as a two-crate Cargo workspace (dateparser library, belt CLI). Runtime dependencies are minimal: chrono 0.4.31 for date/time types, regex 1.10.2 for format matching, and anyhow 1.0.75 for error propagation, plus optional js-sys/wasm-bindgen behind the wasm feature for browser targets. Dev-dependencies add chrono-tz for named-timezone test cases and criterion (default features disabled, since its default rayon dependency breaks WASM builds) for the benchmark suite in benches/parse.rs. GitHub Actions runs a CI workflow plus a separate release workflow that appears to publish the belt CLI as a Homebrew formula.

Code Quality Tests live inline in lib.rs under #[cfg(test)] mod tests, using a table-driven style — vectors of (name, input, expected, truncation-mode) tuples run through shared assertion loops — covering local-timezone parsing, UTC parsing, and explicit EDT/EST/UTC/Local default-timezone scenarios. Error handling is unified through anyhow::Result, with a single terminal error when no format matches, so callers deal with one error type rather than parser-specific variants. Internally, the format methods make heavy use of unwrap()/expect() when constructing NaiveDate/NaiveTime values from already-validated regex captures — reasonable given the values are pre-checked by the same regex, but it means a malformed capture would panic rather than surface as a Result::Err. Five runnable examples under examples/ supplement the test suite as lightweight, always-compiled integration coverage.

API Design The public surface is deliberately small: three free functions plus a DateTimeUtc newtype implementing std::str::FromStr, so callers can parse either explicitly (dateparser::parse(...)) or idiomatically ("...".parse::<DateTimeUtc>()) and get back a standard chrono::DateTime<Utc> rather than a bespoke type. Nearly every public item carries a doc-comment example that also runs as a cargo test doctest, so the published documentation stays verified against the actual API. The bundled belt CLI is a working usage example beyond the crate’s own docs. The tradeoff is scope over flexibility: the format list is fixed and extensive, but there’s no strptime-style custom-format escape hatch for inputs outside the built-in set.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search