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.
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.
- 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) orchronousing cargo features. You get the sameRosettaDateTimeAPI 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-bindgensupport.
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"] }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();
}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
}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个小时前"
}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"
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-languagesWe use criterion for tracking parsing performance. To run the benchmarks:
cargo benchEnable 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 | 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. |
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"This project is dual-licensed under either the MIT License or the Apache License (Version 2.0).