rosetta-date 0.3.0

A powerful, multi-language, multi-format timezone-aware date parser
Documentation

Rosetta-Date 🕰️🌐

A high-performance, timezone-aware, and highly modular multi-language date parsing library for Rust and WebAssembly. Inspired by Python's dateparser and Rust's dateparser.

Crates.io Documentation License

rosetta-date acts as a unified abstraction over popular Rust datetime libraries (time or chrono). It compiles language dictionaries directly into your binary via &'static constants, guaranteeing zero-cost runtime performance for internationalization.

Features ✨

  • Multi-Language NLP Parsing: Understands absolute ("11 Décembre 2014 à 09:00", "13 января 2015 г. в 13:34") and relative time ("2 hours ago", "3小时前", "há 3 horas") in 12 different languages.
  • Unified Backend: Choose between time (default) or chrono using cargo features. You get the same RosettaDateTime API regardless of the backend.
  • Zero-Cost I18n: Language data is strictly statically compiled. You only pay (in binary size) for the languages you explicitly enable via feature flags.
  • Smart Heuristics: Cascading fallback engine (Standard RFC/ISO → Slash/Dot Formats → Natural Language Processing).
  • Timezone Aware: Extracts trailing timezones, recognizes IANA timezones (e.g., Asia/Shanghai), numeric offsets (+08:00), and 30+ abbreviations (PST, UTC, CST).
  • WebAssembly Ready: First-class wasm-bindgen support.

Installation 📦

Add rosetta-date to your Cargo.toml:

[dependencies]
# Default includes English support and the `time` backend
rosetta-date = "0.1.0"

# Example: Use Chrono backend, add Chinese & Spanish support
# rosetta-date = { version = "0.1.0", default-features = false, features = ["chrono-backend", "lang-en", "lang-zh", "lang-es"] }

# Example: Enable all languages and WASM bindings
# rosetta-date = { version = "0.1.0", features = ["all-languages", "wasm"] }

Quick Start 🚀

Multi-Language Parsing

use rosetta_date::parse;

fn main() {
    // English
    let dt = parse("October 21, 2014 09:00 AM").unwrap();
    
    // French
    let dt_fr = parse("Le 11 Décembre 2014 à 09:00").unwrap();
    
    // Spanish
    let dt_es = parse("Martes 21 de Octubre de 2014").unwrap();
    
    // Russian
    let dt_ru = parse("13 января 2015 г. в 13:34").unwrap();
    
    // Thai
    let dt_th = parse("1 ตุลาคม 2005, 1:00 AM").unwrap();
    
    // Chinese (RFC 3339 / ISO 8601 fallback)
    let dt_zh = parse("2023-10-15T12:30:45+08:00").unwrap();
}

Relative Time Parsing (NLP)

use rosetta_date::{parse, parse_with_options, ParseOptions, RosettaDateTime};

fn main() {
    // Relative to "now"
    let dt_en = parse("2 hours ago").unwrap();
    let dt_ko = parse("2시간 전").unwrap();     // Korean
    let dt_it = parse("2 ore fa").unwrap();     // Italian
    let dt_pt = parse("há 3 horas").unwrap();   // Portuguese
    
    // With specific base time
    let base = RosettaDateTime::now_utc();
    let opts = ParseOptions {
        base_time: Some(base),
        // You can restrict which languages to detect:
        // languages: Some(vec![&rosetta_date::i18n::zh::CHINESE]),
        ..Default::default()
    };
    
    let dt_zh = parse_with_options("3天后", &opts).unwrap(); // 3 days later
}

Date Formatting & Time Ago

use rosetta_date::{RosettaDateTime, format_datetime, time_ago, i18n};

fn main() {
    let dt = RosettaDateTime::now_utc();
    
    // Strftime formatting translated to target language
    let formatted_es = format_datetime(&dt, "%A, %d de %B de %Y", &i18n::es::SPANISH).unwrap();
    println!("{}", formatted_es); // e.g. "lunes, 15 de octubre de 2023"
    
    // Relative "Time Ago" formatting
    let dt_past = dt.add_seconds(-3600 * 2); // 2 hours ago
    
    println!("{}", time_ago(&dt_past, &dt, &i18n::en::ENGLISH)); // "2 hours ago"
    println!("{}", time_ago(&dt_past, &dt, &i18n::zh::CHINESE)); // "2个小时前"
}

Supported Date Formats

We support parsing an extensive list of date formats, inspired by the above libraries:

# unix timestamp
"1511648546", "1620021848429", "1620024872717915000"
# rfc3339 / rfc2822
"2021-05-01T01:17:02.604456Z", "Wed, 02 Jun 2021 06:31:39 GMT"
# postgres timestamp yyyy-mm-dd hh:mm:ss z
"2019-11-29 08:08-08", "2017-07-19 03:21:51+00:00"
# yyyy-mm-dd hh:mm:ss
"2014-04-26 05:24:37 PM", "2021-04-30 21:14:10.052282"
# yyyy-mm-dd hh:mm:ss z
"2017-11-25 13:31:15 PST", "2014-12-16 06:20:00 UTC", "2014-04-26 13:13:43 +0800"
# yyyy-mm-dd / yyyy-mm-dd z
"2021-02-21", "2021-02-21 PST", "2020-07-20+08:00"
# hh:mm:ss / hh:mm:ss z
"01:06:06", "4:00pm", "6:00 AM PST", "6:00pm UTC"
# Mon dd hh:mm:ss
"May 6 at 9:24 PM", "May 27 02:45:27"
# Mon dd, yyyy, hh:mm:ss / Mon dd, yyyy hh:mm:ss z
"May 8, 2009 5:57:51 PM", "September 17, 2012 at 10:09am PST"
# yyyy-mon-dd / Mon dd, yyyy
"2021-Feb-21", "May 25, 2021", "October 7, 1970", "oct. 7, 70"
# dd Mon yyyy hh:mm:ss / dd Mon yyyy
"12 Feb 2006, 19:17", "14 May 2019 19:11:40.164", "03 February 2013"
# mm/dd/yyyy hh:mm:ss
"4/8/2014 22:05", "8/8/1965 12:00:00 AM", "03/19/2012 10:11:59.3186369"
# mm/dd/yyyy / yyyy/mm/dd hh:mm:ss / yyyy/mm/dd
"3/31/2014", "2014/4/8 22:05", "2014/3/31"
# mm.dd.yyyy / yyyy.mm.dd
"03.31.2014", "08.21.71", "2014.03.30", "2014.03"
# yymmdd hh:mm:ss mysql log
"171113 14:14:20"
# chinese yyyy mm dd hh mm ss / chinese yyyy mm dd
"2014年04月08日11时25分18秒", "2014年04月08日"
# typical multi-language formats
"29 agosto 2023", "29 de agosto de 2023", "29. August 2023", "30. Oktober 2024", "29 août 2023", "2023年8月26日", "8 May 2023"

Examples 💡

You can find various usage examples in the examples/ directory. Run them easily with Cargo:

cargo run --example basic_parsing
cargo run --example relative_time
cargo run --example i18n_formatting --features all-languages
cargo run --example multilang_dates --features all-languages

Benchmarks 📊

We use criterion for tracking parsing performance. To run the benchmarks:

cargo bench

Supported Languages 🌍

Enable specific languages via Cargo feature flags (e.g., features = ["lang-es", "lang-fr"]) or enable them all using all-languages.

Language Feature Flag Language Feature Flag
English lang-en (Default) Japanese lang-ja
Chinese lang-zh Russian lang-ru
Spanish lang-es Turkish lang-tr
French lang-fr Thai lang-th
German lang-de Portuguese lang-pt
Italian lang-it Korean lang-ko

Feature Flags ⚙️

Feature Description
time-backend (Default) Uses the lightweight time crate as the core date engine.
chrono-backend Uses chrono as the core date engine instead.
all-languages Compiles all 12 supported language dictionaries.
lang-* Granular control over which languages to include in the binary.
wasm Exposes a JS/TS API via wasm-bindgen (parseDate, timeAgo, etc.).
serde Implements Serialize and Deserialize on RosettaDateTime and RosettaDelta.

WebAssembly (WASM) Support 🌐

rosetta-date provides out-of-the-box WASM bindings.

Compile with: wasm-pack build --target web --features "wasm,all-languages"

import init, { parseDate, timeAgo } from './pkg/rosetta_date.js';

await init();

// Parse any language to ISO string
const isoDate = parseDate("13 января 2015 г. в 13:34");
console.log(isoDate); 

// Generate translated "time ago" string
const agoStr = timeAgo("2023-10-10T12:00:00Z", "es"); 
console.log(agoStr); // "hace 2 días"

License 📄

This project is dual-licensed under either the MIT License or the Apache License (Version 2.0).