| Crates.io | tempotime |
| lib.rs | tempotime |
| version | 0.1.3 |
| created_at | 2025-10-30 14:53:10.056467+00 |
| updated_at | 2025-10-30 18:52:36.53873+00 |
| description | Luxon.js in Rust โ immutable, chainable, IANA timezone-aware dates |
| homepage | |
| repository | https://github.com/hyoussef07/tempotime |
| max_upload_size | |
| id | 1908384 |
| size | 150,920 |
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.
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 dates
let dur = Duration::from_object(&[
("weeks", 2),
("days", 3),
("hours", 4),
]);
dur.as_unit("days") // Convert to days
dur.to_object() // Export as HashMap
use 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.
.local() returns UTCEnable features when you need:
chrono)tz)tz)chronochrono:
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");
timeTempotime provides:
| 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 bench
Contributions are welcome! This is a community-driven port of Luxon.js to Rust.
Licensed under either of:
at your option.
This project is inspired by Luxon.js, the modern successor to Moment.js.
โญ If you find Tempotime useful, please consider giving it a star on GitHub! โญ
Made with โค๏ธ for the Rust community