For Developers

Unix Timestamp vs. ISO 8601 vs. RFC 3339

Three formats, three different jobs. Picking the wrong one for a given context is one of the most common — and most avoidable — sources of timestamp bugs.

If you've worked with timestamps across more than one system, you've run into all three of these: a raw Unix timestamp like 1770000000, an ISO 8601 string like 2026-02-02T03:00:00Z, and something that looks almost identical but calls itself RFC 3339. They overlap heavily, which is exactly why mixing them up causes real bugs.

Unix timestamp: a number, not a format

A Unix timestamp is just an integer — seconds (or milliseconds) since January 1, 1970 UTC. It has no built-in notion of timezone, calendar, or human readability; it's purely a machine-friendly count. Use it when you need fast arithmetic, compact storage, or guaranteed unambiguous sorting, and don't need a human to read the raw value.

ISO 8601: a broad international standard

ISO 8601 is a much larger standard than most people realize — it defines date-only formats (2026-02-02), time-only formats, durations (P3Y6M4D), repeating intervals, and multiple ways to represent a timezone offset, including the option to omit it entirely. That flexibility is useful, but it also means "this is ISO 8601" doesn't fully pin down what a string looks like — two ISO 8601-compliant timestamps can differ in ways that break a strict parser expecting one specific variant.

RFC 3339: ISO 8601's stricter, internet-facing sibling

RFC 3339 takes the datetime portion of ISO 8601 and narrows it into one specific, unambiguous profile designed for use on the internet — a fixed YYYY-MM-DDTHH:MM:SSZ-style shape with an explicit, mandatory timezone offset (or Z for UTC). Almost every "ISO 8601 timestamp" you'll see in a real-world API is technically an RFC 3339 timestamp, because RFC 3339's strictness is exactly what makes it reliable to parse automatically. If you're designing an API, RFC 3339 — not the broader ISO 8601 spec — is the more precise thing to say you're using.

The single most common bug: a missing timezone offset

A string like 2026-02-02T03:00:00 with no trailing Z or offset is technically valid under some interpretations of ISO 8601, but it's genuinely ambiguous — is that 3 AM UTC, or 3 AM in whatever timezone the reading system assumes? Different libraries resolve this differently, some defaulting to UTC and others to local system time, which is how the exact same string ends up meaning two different real-world moments depending on which system reads it. RFC 3339's requirement of an explicit offset exists specifically to close this gap.

Which one to actually use

For anything crossing a network boundary — API requests and responses, webhooks, log aggregation — use RFC 3339 with an explicit UTC offset; it's readable, sorts correctly as plain text, and no parser has to guess. For internal storage and computation, a Unix timestamp (in a real timestamp column, not a string) is usually more efficient. Reach for the fuller ISO 8601 spec mainly when you specifically need one of its extra features, like representing a duration or a repeating interval, that RFC 3339 doesn't cover.

Related

Related tools & reading