A Luxon.js-inspired datetime library for Rust with zero dependencies by default.
Tempotime brings the elegant, immutable, and chainable API of Luxon.js to Rust, while offering unique advantages like optional zero-dependency operation for UTC-only use cases.
use tempotime::{dt, Duration};
let result = dt()
.plus(&Duration::from_object(&[("weeks", 2), ("days", 3)]))
.start_of("day")
.to_format("MMMM do, yyyy 'at' h:mm a");
println!("{}", result);
// Output: "November 16th, 2025 at 12:00 am"Use only std::time for UTC operations β no external crates required. Perfect for microservices, CLI tools, and fast compilation.
All operations return new instances, preventing common date manipulation bugs.
Write clean, readable date manipulation code with method chaining.
Enable IANA timezone database when you need it with the tz feature.
Familiar, intuitive token-based formatting inspired by Luxon.js.
- Zero-deps mode: ~175 KB
- With timezone support: ~2 MB
Add to your Cargo.toml:
# Zero-deps mode (UTC only, minimal binary size)
[dependencies]
tempotime = "0.1"# Accurate month/year arithmetic
tempotime = { version = "0.1", features = ["chrono"] }
# Full IANA timezone support
tempotime = { version = "0.1", features = ["tz"] }
# JSON serialization
tempotime = { version = "0.1", features = ["serde"] }
# All features
tempotime = { version = "0.1", features = ["tz", "serde"] }use tempotime::{dt, DateTime, Duration};
// Get current time
let now = dt();
// Parse from ISO 8601
let date = DateTime::from_iso("2025-10-30T14:30:00Z").unwrap();
// Add/subtract durations
let tomorrow = now.plus(&Duration::from_object(&[("days", 1)]));
let last_week = now.minus(&Duration::from_object(&[("weeks", 1)]));
// Format output
println!("{}", tomorrow.to_format("yyyy-MM-dd HH:mm:ss"));use tempotime::{dt, Duration};
let result = dt()
.plus(&Duration::from_object(&[("days", 3), ("hours", 2)]))
.start_of("day")
.to_format("EEEE, MMMM do");
println!("{}", result); // "Saturday, November 2nd"// Creation
DateTime::now() // Current UTC time
DateTime::from_iso("2025-10-30T14:30:00Z") // Parse ISO 8601
DateTime::from_format("Oct 30, 2025", "MMM dd, yyyy") // Parse custom format
// Manipulation
dt.plus(&Duration::from_object(&[("days", 7)])) // Add duration
dt.minus(&Duration::from_object(&[("hours", 3)])) // Subtract duration
dt.start_of("day") // Round down
dt.end_of("month") // Round up
dt.set_zone("America/New_York") // Convert timezone
// Formatting
dt.to_iso() // ISO 8601 string
dt.to_format("yyyy-MM-dd") // Custom format
dt.to_locale_string(DateTime::DATE_FULL) // Locale preset
// Comparison
dt.diff(&other, "days") // Difference in days
dt > other_dt // Compare dateslet dur = Duration::from_object(&[
("weeks", 2),
("days", 3),
("hours", 4),
]);
dur.as_unit("days") // Convert to days
dur.to_object() // Export as HashMapuse tempotime::{dt, Duration, Interval};
let start = dt();
let end = start.clone().plus(&Duration::from_object(&[("days", 30)]));
let interval = Interval::from_date_times(start, end);
interval.contains(&dt()) // Check if in range
interval.length("days").as_unit("days") // Get length| Token | Output | Description |
|---|---|---|
yyyy |
2025 | 4-digit year |
yy |
25 | 2-digit year |
MMMM |
October | Full month name |
MMM |
Oct | Short month name |
MM |
10 | 2-digit month |
dd |
30 | 2-digit day |
do |
30th | Day with ordinal |
EEEE |
Wednesday | Full weekday |
EEE |
Wed | Short weekday |
HH |
14 | 24-hour (padded) |
hh |
02 | 12-hour (padded) |
mm |
30 | Minutes |
ss |
05 | Seconds |
SSS |
123 | Milliseconds |
a |
pm | AM/PM |
'text' |
text | Literal text |
let dt = dt();
dt.to_format("yyyy-MM-dd"); // "2025-10-30"
dt.to_format("MMMM do, yyyy"); // "October 30th, 2025"
dt.to_format("EEEE 'at' h:mm a"); // "Wednesday at 2:30 pm"By default, Tempotime uses only std::time::SystemTime for UTC timestamps.
- Zero external dependencies
- Fast compilation (~2-3 seconds)
- Tiny binary (~175 KB)
- Full API compatibility
- UTC only
- Approximate month/year math
- No DST support
.local()returns UTC
Enable features when you need:
- β Accurate month/year arithmetic (
chrono) - β Timezone conversions (
tz) - β DST handling (
tz)
chrono:
use chrono::{Utc, Duration};
let dt = Utc::now()
.checked_add_signed(Duration::days(3))
.unwrap()
.format("%Y-%m-%d")
.to_string();tempotime:
use tempotime::{dt, Duration};
let dt = dt()
.plus(&Duration::from_object(&[("days", 3)]))
.to_format("yyyy-MM-dd");Tempotime provides:
- β Immutable-by-default design
- β Luxon-style formatting
- β Object-based durations
- β More chainable API
- β Optional zero-dependency mode
| Feature | Zero-Deps | chrono |
tz |
|---|---|---|---|
| Binary Size | ~175 KB | ~2 MB | ~2 MB |
| Dependencies | 0 | 1 | 2 |
| Compilation | ~2-3s | ~15-20s | ~25-30s |
| UTC Operations | β | β | β |
| Month/Year Math | ~30d/365d | Accurate | Accurate |
| Timezones | UTC only | UTC only | IANA (600+) |
| DST Support | β | β | β |
Run the included examples:
# Basic demo
cargo run --example demo
# Timezone example
cargo run --example timezone --features tz
# Zero-deps demonstration
cargo run --example zero_deps# Run tests (zero-deps mode)
cargo test
# Run tests with all features
cargo test --all-features
# Run benchmarks
cargo benchContributions are welcome! This is a community-driven port of Luxon.js to Rust.
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
This project is inspired by Luxon.js, the modern successor to Moment.js.
- π¦ Crates.io: https://crates.io/crates/tempotime
- π Documentation: https://docs.rs/tempotime
- π GitHub: https://github.com/hyoussef07/tempotime
- π Luxon.js: https://moment.github.io/luxon/
β If you find Tempotime useful, please consider giving it a star on GitHub! β
Made with β€οΈ for the Rust community