ISO 8601 vs Unix Timestamp: When to Use Which
ISO 8601 and Unix timestamps compared: readability, storage, sortability, timezone handling, and parsing — with conversion examples in JavaScript, Python, and Go.
Table of contents
TL;DR: Use Unix timestamps when you need to do arithmetic, store compact values, or communicate between systems. Use ISO 8601 strings when humans need to read the value directly, when you are working with APIs that require a standard format, or when timezone information must be explicit. The two are interchangeable with a one-line conversion in any language.
Quick decision matrix:
| Need | Use |
|---|---|
| Database storage, sorting | Unix (integer) |
| API request/response body | ISO 8601 |
| Log files read by humans | ISO 8601 |
| Internal time arithmetic | Unix (integer) |
| HTTP headers | RFC 2822 (subset of ISO 8601) |
| Discord / Slack timestamps | Unix (seconds) |
| JSON with timezone info | ISO 8601 with offset |
Design philosophy of each format
Unix timestamps are a machine-first design. They represent a single absolute moment in time as a plain integer — no formatting, no timezone ambiguity, no separators. Every system that understands Unix epoch can interpret the value identically. Arithmetic is trivial: adding 86400 to a Unix timestamp gives you exactly one day later (ignoring leap seconds).
ISO 8601 is a human-readable international standard published by the International Organization for Standardization. It defines a family of text-based formats for dates, times, durations, and intervals. The most common form is the combined date-time string: 2026-05-09T18:00:00Z. The Z means UTC; an offset like +09:00 makes the timezone explicit. ISO 8601 is designed to be sortable as a string (because of its largest-to-smallest field ordering) and legible to anyone familiar with the ISO convention.
Side-by-side comparison
Readability
| Format | Example | Human-readable? |
|---|---|---|
| Unix (seconds) | 1746785400 | No — requires a converter |
| Unix (milliseconds) | 1746785400000 | No |
| ISO 8601 (UTC) | 2026-05-09T18:00:00Z | Partially — needs ISO familiarity |
| ISO 8601 (with offset) | 2026-05-09T18:00:00+09:00 | Yes — timezone explicit |
| RFC 2822 | Sat, 09 May 2026 18:00:00 +0000 | Yes — natural language month |
ISO 8601 wins on readability for humans, especially with an explicit offset. Unix timestamps require a tool or mental math to interpret.
Storage size
| Format | Size |
|---|---|
| Unix (32-bit int) | 4 bytes |
| Unix (64-bit int) | 8 bytes |
| ISO 8601 basic | 15 bytes (20260509T180000Z) |
| ISO 8601 extended | 20 bytes (2026-05-09T18:00:00Z) |
| ISO 8601 with ms | 24 bytes (2026-05-09T18:00:00.000Z) |
For high-volume storage — billions of log entries, time-series databases — 8 bytes vs 24 bytes per record is significant. Unix timestamps win on compactness.
Sortability
Both formats sort correctly as-is, but only in specific forms.
Unix timestamps always sort lexicographically if they are the same precision and format (integer or zero-padded). 1746785400 < 1746871800 is trivially true.
ISO 8601 strings sort correctly as text only when all values use the same UTC offset (ideally Z). Mixing offsets breaks string sorting: 2026-05-09T18:00:00+09:00 and 2026-05-09T10:00:00Z represent the same moment, but sort differently as strings. Normalize to UTC before string-sorting ISO 8601 values.
Timezone handling
| Format | Timezone representation |
|---|---|
| Unix timestamp | Always UTC (by definition) |
| ISO 8601 with Z | UTC, explicit |
| ISO 8601 with offset | Specific offset, not necessarily a named timezone |
| ISO 8601 without Z | Ambiguous — no timezone (local time, dangerous) |
Unix timestamps eliminate timezone ambiguity entirely. The moment is always UTC; the display timezone is a concern for the presentation layer.
ISO 8601 with a Z suffix or an explicit offset (e.g., +05:30) makes the timezone clear. ISO 8601 without a suffix is a “naive” timestamp — it does not tell you which timezone the time is in. This is the most dangerous form and should be avoided for data exchange.
Parsing complexity
Unix timestamps parse with a single integer parse call in any language. No format string, no locale handling, no separator logic.
ISO 8601 is standardized but has many optional components: the T separator may be a space, milliseconds may or may not be present, offsets may or may not be included, and week-based dates (2026-W20-6) are valid but rare. Most languages handle the common forms natively, but edge cases require a dedicated library or careful validation.
When to use which (decision guide)
Use Unix timestamps when:
- Storing timestamps in a database column where you will do range queries or arithmetic
- Communicating between internal services where both sides can agree on precision (seconds vs milliseconds)
- Building Discord or Slack messages (both platforms require Unix seconds)
- Writing cron job timestamps, session expiry, or JWT
exp/iatclaims - Logging at high volume and storage efficiency matters
Use ISO 8601 when:
- Writing API responses that humans or external tools may read
- Writing log messages that operators will scan
- Serializing timestamps to JSON (ISO 8601 is the de facto standard)
- You need to represent a timezone offset other than UTC explicitly
- Working with calendar systems where the year/month/day breakdown is meaningful
Use neither (use your language’s native type) when:
- Doing date arithmetic within a single service — use the language’s datetime object internally
- Storing timestamps in PostgreSQL — use the native
TIMESTAMP WITH TIME ZONEtype
Conversion code examples
JavaScript
// ISO 8601 string → Unix seconds
const iso = '2026-05-09T18:00:00Z';
const unixSeconds = Math.floor(new Date(iso).getTime() / 1000);
console.log(unixSeconds); // 1746785400
// Unix seconds → ISO 8601 string
const ts = 1746785400;
const isoString = new Date(ts * 1000).toISOString();
console.log(isoString); // '2026-05-09T18:00:00.000Z'
// ISO 8601 with milliseconds (common in JSON APIs)
const isoMs = new Date(ts * 1000).toISOString(); // includes .000Z
Python
from datetime import datetime, timezone
# ISO 8601 string → Unix seconds
iso = '2026-05-09T18:00:00Z'
dt = datetime.fromisoformat(iso.replace('Z', '+00:00')) # Python < 3.11
# or: dt = datetime.fromisoformat(iso) # Python 3.11+
unix_seconds = int(dt.timestamp())
print(unix_seconds) # 1746785400
# Unix seconds → ISO 8601 string
ts = 1746785400
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
iso_string = dt.isoformat()
print(iso_string) # '2026-05-09T18:00:00+00:00'
# With trailing Z (common preference)
iso_z = dt.strftime('%Y-%m-%dT%H:%M:%SZ')
print(iso_z) # '2026-05-09T18:00:00Z'
Go
package main
import (
"fmt"
"time"
)
func main() {
// ISO 8601 string → Unix seconds
iso := "2026-05-09T18:00:00Z"
t, err := time.Parse(time.RFC3339, iso)
if err != nil {
panic(err)
}
unixSeconds := t.Unix()
fmt.Println(unixSeconds) // 1746785400
// Unix seconds → ISO 8601 string
ts := int64(1746785400)
t2 := time.Unix(ts, 0).UTC()
isoString := t2.Format(time.RFC3339)
fmt.Println(isoString) // 2026-05-09T18:00:00Z
// With millisecond precision
isoMs := t2.Format(time.RFC3339Nano)
fmt.Println(isoMs) // 2026-05-09T18:00:00Z
}
Related tools
Convert between ISO 8601 and Unix formats interactively:
- epochkit ISO 8601 Converter — parse and format ISO 8601 strings, validate variants
- epochkit Unix Timestamp Converter — convert Unix seconds/milliseconds to readable dates