Time & dates
Concept  ·  SQL & Querying

An epoch number carries no units — seconds, milliseconds, and micros are just magnitudes — so the wrong unit produces a valid timestamp in the wrong millennium, no error.

Epoch values are dimensionless integers by the time they reach SQL — the units lived in the producer's head. The conversion function assumes its unit, and a mismatch doesn't fail — it lands 1000× deep in the future or 1970 in the past. The tells: 10 digits ≈ seconds-now, 13 ≈ ms, 16 ≈ µs; the guard is a plausible-range assertion (this is why 'row lands in year 55840' belongs in every ingestion test).

See it break
logs
idts_ms
11700000000000
The trap
SELECT
  id,
  strftime(to_timestamp(ts_ms ), '%Y') AS yr
FROM
  logs;
The fix
SELECT
  id,
  strftime(to_timestamp(ts_ms / 1000), '%Y-%m') AS ym
FROM
  logs;
INPUTYour queryThe fix
1558402023-11

A millisecond epoch fed to a seconds converter landed in the year 55840 — an epoch number carries no units, so the wrong magnitude produces a valid timestamp in the wrong millennium, no error; dividing by 1000 first lands it in Nov 2023.

The rule

Unit-suffixed column names; explicit division with a comment; plausible-range assertions at ingestion.

Shows up elsewhere
Implicit casts in comparisonsHalf-open intervals
Try one →Prove it in practice →