Timestamp Converter — Python 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 Python implementation — the same logic the interactive tool runs, in a shareable, citable form.
"""Unix epoch (seconds & milliseconds) <-> human forms: ISO 8601, UTC
string, local date string, and relative time ("3 hr ago" / "in 2 day").
Language: Python
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 via the standard
``datetime`` module. ``relative_time`` buckets ``|now - t|`` into
sec/min/hr/day/month/yr using the same 60s / 60m / 24h / 30d / 365d
thresholds and signs the phrase ("ago" / "in …"). ``now_ms`` is a
parameter so the function is deterministic and unit-testable; it defaults
to :func:`time.time` multiplied to milliseconds.
"""
from __future__ import annotations
import time
from datetime import datetime, timezone
_INVALID = "—"
def relative_time(ms: int, now_ms: int | None = None) -> str:
"""Return "3 hr ago" / "in 2 day" / "42 sec ago", mirroring the island.
Buckets the absolute distance from *now_ms* into sec/min/hr/day/month/
yr, rounds to the nearest whole unit, and prefixes "in " (future) or
suffixes " ago" (past).
"""
if now_ms is None:
now_ms = int(time.time() * 1000)
diff = ms - now_ms
abs_s = abs(diff) / 1000.0
if abs_s < 60:
n, unit = round(abs_s), "sec"
elif abs_s < 3600:
n, unit = round(abs_s / 60), "min"
elif abs_s < 86400:
n, unit = round(abs_s / 3600), "hr"
elif abs_s < 86400 * 30:
n, unit = round(abs_s / 86400), "day"
elif abs_s < 86400 * 365:
n, unit = round(abs_s / (86400 * 30)), "month"
else:
n, unit = round(abs_s / (86400 * 365)), "yr"
phrase = f"{n} {unit}"
return f"{phrase} ago" if diff < 0 else f"in {phrase}"
def _iso8601(dt: datetime) -> str:
# Date.toISOString() renders UTC with milliseconds and a "Z".
ms = dt.microsecond // 1000
return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{ms:03d}Z"
def format_timestamp(secs: int, now_ms: int | None = None) -> dict[str, str]:
"""Render every form the tool exposes from epoch seconds.
Matches the island's row table: epoch (s), epoch (ms), ISO 8601,
UTC string, local string, and relative time. Invalid instants
render an em dash, exactly like the live UI.
"""
try:
utc = datetime.fromtimestamp(secs, tz=timezone.utc)
except (OverflowError, OSError, ValueError):
dash = _INVALID
return {
"Epoch (s)": str(secs),
"Epoch (ms)": str(secs * 1000),
"ISO 8601": dash,
"UTC": dash,
"Local": dash,
"Relative": dash,
}
# toUTCString(): "Wed, 14 Jun 2017 07:00:00 GMT" (C locale = English).
utc_str = utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
local = datetime.fromtimestamp(secs).strftime("%Y-%m-%d %H:%M:%S")
return {
"Epoch (s)": str(secs),
"Epoch (ms)": str(secs * 1000),
"ISO 8601": _iso8601(utc),
"UTC": utc_str,
"Local": local,
"Relative": relative_time(secs * 1000, now_ms),
}
def from_iso(iso: str) -> int | None:
"""Parse an ISO 8601 / datetime-local string into epoch seconds.
Mirrors the island's ``<input type="datetime-local">`` handler: parse
the string in the host zone and floor to seconds. Returns ``None`` for
unparseable input (the UI silently no-ops).
"""
text = iso.replace("Z", "+00:00") if iso.endswith("Z") else iso
try:
dt = datetime.fromisoformat(text)
except ValueError:
# Fall back to the datetime-local "YYYY-MM-DDTHH:mm" shape.
for fmt in ("%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M:%S", "%Y-%m-%d"):
try:
dt = datetime.strptime(iso, fmt)
except ValueError:
continue
return int(dt.timestamp())
return None
return int(dt.timestamp())
if __name__ == "__main__":
now_ms = int(time.time() * 1000)
for key, value in format_timestamp(int(time.time()), now_ms).items():
print(f"{key+':':<11} {value}")
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 →