Timestamp Converter — Rust source
Convert Unix epoch timestamps to human-readable dates and back. See seconds, milliseconds, ISO 8601, UTC, local and relative time at once.
This is the Rust implementation — the same logic the interactive tool runs, in a shareable, citable form.
//! Unix epoch (seconds & milliseconds) <-> human forms: ISO 8601, UTC
//! string, and relative time ("3 hr ago" / "in 2 day").
//!
//! Language: Rust
//! CosmoDev polyglot showcase port of the `timestamp` tool.
//! Ported from src/tools/TimestampConverter.tsx — display source, part of
//! CosmoDev's polyglot tool pages.
//!
//! Every form derives from a single epoch-seconds value. Rust's standard
//! library ships no calendar — so this port uses `std::time` for the
//! clock and Howard Hinnant's civil-from-days algorithm (the well-known
//! days <-> (y, m, d) transform) to render ISO 8601 / the UTC string by
//! hand. relative_time() buckets |now - t| into sec/min/hr/day/month/yr
//! with the same thresholds as the island and signs the phrase.
//!
//! Parity note: with no external crates, the host *local* timezone is not
//! readable from std, so the "Local" row falls back to UTC (matching JS
//! behaviour outside a browser tz); the epoch/ISO/UTC/relative rows are
//! fully faithful.
use std::time::{SystemTime, UNIX_EPOCH};
const WEEKDAYS: [&str; 7] = ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"];
const MONTHS: [&str; 12] = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];
/// Calendar instant decoded from a Unix-second timestamp.
struct Civil {
year: i64,
month: usize, // 1..=12
day: u32,
hour: u32,
min: u32,
sec: u32,
weekday: usize, // index into WEEKDAYS; days=0 is Thursday (1970-01-01)
}
/// Howard Hinnant's civil-from-days algorithm — maps a day count since
/// the Unix epoch to a proleptic Gregorian (year, month, day).
fn civil_from_unix(secs: i64) -> Civil {
let days = secs.div_euclid(86_400);
let clock = secs.rem_euclid(86_400);
let weekday = days.rem_euclid(7) as usize;
let z = days + 719_468;
let era = if z >= 0 { z } else { z - 146_096 } / 146_097;
let doe = z - era * 146_097; // [0, 146_096]
let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365; // [0, 399]
let y = yoe + era * 400;
let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365]
let mp = (5 * doy + 2) / 153; // [0, 11]
let d = (doy - (153 * mp + 2) / 5 + 1) as u32; // [1, 31]
let m = if mp < 10 { mp + 3 } else { mp - 9 } as usize; // [1, 12]
let year = if m <= 2 { y + 1 } else { y };
Civil {
year,
month: m,
day: d,
hour: (clock / 3600) as u32,
min: ((clock % 3600) / 60) as u32,
sec: (clock % 60) as u32,
weekday,
}
}
/// Render every UTC form the tool exposes from epoch seconds.
fn format_timestamp(secs: i64) -> (String, String) {
let c = civil_from_unix(secs);
let iso = format!(
"{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.000Z",
c.year, c.month, c.day, c.hour, c.min, c.sec
);
let utc = format!(
"{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT",
WEEKDAYS[c.weekday], c.day, MONTHS[c.month - 1], c.year, c.hour, c.min, c.sec
);
(iso, utc)
}
/// "3 hr ago" / "in 2 day" / "42 sec ago", mirroring the island.
/// now_ms is a parameter so the result is deterministic and testable.
fn relative_time(ms: i64, now_ms: i64) -> String {
let diff = ms - now_ms;
let abs = diff.unsigned_abs() as i64;
const MIN: i64 = 60_000;
const HR: i64 = 3_600_000;
const DAY: i64 = 86_400_000;
let (n, unit) = if abs < MIN {
((abs + 500) / 1000, "sec")
} else if abs < HR {
((abs + MIN / 2) / MIN, "min")
} else if abs < DAY {
((abs + HR / 2) / HR, "hr")
} else if abs < DAY * 30 {
((abs + DAY / 2) / DAY, "day")
} else if abs < DAY * 365 {
((abs + DAY * 15) / (DAY * 30), "month")
} else {
((abs + DAY * 182) / (DAY * 365), "yr")
};
let phrase = format!("{n} {unit}");
if diff < 0 {
format!("{phrase} ago")
} else {
format!("in {phrase}")
}
}
fn main() {
let now_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_millis() as i64)
.unwrap_or(0);
let secs = now_ms / 1000;
println!("Epoch (s): {secs}");
println!("Epoch (ms): {}", secs * 1000);
let (iso, utc) = format_timestamp(secs);
println!("ISO 8601: {iso}");
println!("UTC: {utc}");
println!("Relative: {}", relative_time(secs * 1000, now_ms));
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →