Timestamps & Timezones Cheat Sheet
Quick reference for time handling: ISO 8601, Unix timestamps, UTC, offsets, DST, and formatting patterns across languages.
Most time bugs come from confusing instants (absolute moments in time) with local representations. The rules: store instants in UTC, communicate in ISO 8601 with an offset, and only convert to a local timezone at the display boundary.
ISO 8601 — The Wire Format
| Form | Example |
|---|---|
UTC (Z) | 2026-08-11T14:30:00Z |
| With offset | 2026-08-11T14:30:00+03:00 |
| Date only | 2026-08-11 |
| Date + time, no zone | 2026-08-11T14:30:00 (ambiguous — avoid) |
| Week date | 2026-W33-2 |
| Ordinal date | 2026-223 |
Always communicate with an explicit offset or Z. A bare 2026-08-11T14:30:00 without a zone is ambiguous across systems.
Unix Timestamps
Unix time counts seconds since 1970-01-01T00:00:00Z (UTC). It is timezone-independent — the same number is the same instant everywhere.
Date.now() / 1000 // seconds (float)
Math.floor(Date.now() / 1000)
new Date(1780000000000) // ms → Date
import time, datetime
time.time() # seconds
datetime.datetime.fromtimestamp(1780000000, tz=datetime.timezone.utc)
| Precision | Range | Use |
|---|---|---|
| Seconds | 1780000000 | Common API default |
| Milliseconds | 1780000000000 | JS Date.now() |
| Microseconds | 1780000000000000 | Python datetime |
| Nanoseconds | 1780000000000000000 | Go, Rust SystemTime |
UTC, Offsets, and DST
| Term | Meaning | Example |
|---|---|---|
| UTC | The reference time, no offset | 14:30:00Z |
| Offset | Fixed difference from UTC | +03:00, -05:00 |
| IANA timezone | Region-based rules incl. DST | Europe/Istanbul, America/New_York |
| DST | Seasonal clock shift | +03:00 in summer, +02:00 in winter |
Never store a fixed offset as "the timezone." Offsets change with DST; IANA names encode the rules. +03:00 is not Europe/Istanbul.
# IANA-aware (stdlib from 3.9+)
from zoneinfo import ZoneInfo
now = datetime.datetime.now(ZoneInfo("Europe/Istanbul"))
const date = new Date();
console.log(date.toLocaleString("en-US", { timeZone: "Europe/Istanbul" }));
Formatting Patterns
// JS
new Date().toISOString(); // 2026-08-11T14:30:00.000Z
new Intl.DateTimeFormat("en-GB", { dateStyle: "medium", timeStyle: "short", timeZone: "UTC" }).format(new Date());
# Python strftime
datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
| Code | Meaning | Output |
|---|---|---|
%Y-%m-%d / YYYY-MM-DD | Date | 2026-08-11 |
%H:%M:%S / HH:mm:ss | Clock | 14:30:00 |
%z / +03:00 | ISO offset | +0300 / +03:00 |
%Z | Zone name | UTC, EEST |
%s | Unix seconds | 1780000000 |
Common Pitfalls
[!WARNING] Never do arithmetic on wall-clock times across DST boundaries. Treat
2026-03-29 02:30in a DST zone as potentially nonexistent/ambiguous — parse to UTC first, then render.
[!TIP] Store everything in UTC internally; use IANA timezone names in config, not fixed offsets; format for humans only at the very last step.