#duration-parser #format-duration #parse-duration

fmt-dur

Strict human-readable Duration parser/formatter: '2d3h4m', '90s', '1.5h'. Enforces unit order, no duplicates, and precise decimal rules.

2 releases

Uses new Rust 2024

0.1.3 Nov 16, 2025
0.1.1 Sep 17, 2025

#240 in Value formatting

MIT/Apache

30KB
627 lines

Identical to docs in crates.io


lib.rs:

fmt_dur - strict Duration parsing/formatting.

Grammar (strict by default)

Input := Segment { Segment }
Segment := Number Unit
Number := DIGIT+ [ "." DIGIT{1,9} ]   // decimal allowed at most once, and only in the last Segment
Unit   := "d" | "h" | "m" | "s" | "ms" | "us" | "ns"

Rules

  • Units must appear in strictly descending order: d > h > m > s > ms > us > ns
  • No duplicate units
  • No spaces/underscores; lowercase only (enable "loose" feature to allow spaces/underscores and case-insensitive)
  • At least one segment must be present (e.g., "0s" is valid)
  • Up to 9 fractional digits (nanosecond precision). Fraction may appear only on the last segment.

Examples

Valid duration strings:

  • "2d3h4m"
  • "90s"
  • "1.5h"
  • "250ms"
  • "1m30s"
  • "1m30.5s"
  • "750us"
  • "10ns"

Usage

use std::time::Duration;

// Parse a duration string
let duration = parse("1.5h").unwrap();
assert_eq!(duration, Duration::from_secs(5400));

// Parse with custom options (saturating on overflow)
let duration = parse_with("1.5h", &ParseOptions::strict().saturating()).unwrap();

// Format a duration (default: mixed-units; decimals only on the last unit)
let formatted = format(duration);
assert_eq!(formatted, "1h30m");

// Format with custom options (largest unit with decimal)
let formatted = format_with(duration, &FormatOptions::largest_unit_decimal());
assert_eq!(formatted, "1.5h");

Features

  • loose: Allows spaces and underscores between segments and case-insensitive units (ordering still enforced).
  • serde: Enables serde::{Serialize, Deserialize} for DurationStr using this format.

Dependencies

~155KB