Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

Unix seconds vs milliseconds

On this page
  1. How big is each, in practice
  2. Where each is the convention
    1. Seconds
    2. Milliseconds
    3. Microseconds
    4. Nanoseconds
  3. The 1000× bug
  4. Detection rules
  5. API design
  6. Common library defaults
  7. Try the tools

TL;DR. When in doubt, use Unix seconds — the older, more portable unit. Use milliseconds when the API specifically demands them (JavaScript, Java) or when sub-second precision matters. Mismatched units cause the single most common time bug: dates that are off by a factor of 1000.

How big is each, in practice

For 2025-01-01 00:00:00 UTC:

Seconds:        1735689600           (10 digits)
Milliseconds:   1735689600000        (13 digits)
Microseconds:   1735689600000000     (16 digits)
Nanoseconds:    1735689600000000000  (19 digits)

The number-of-digits heuristic is reliable enough that the converter auto-detects format from magnitude alone.

Where each is the convention

Seconds

Milliseconds

Microseconds

Nanoseconds

The 1000× bug

The single most common time bug in production code:

// Bug: API returned seconds; passed straight to JavaScript Date
const ts = await fetchTimestamp();   // 1735689600 (seconds, from API)
const date = new Date(ts);
console.log(date.toISOString());
// → "1970-01-21T02:08:09.600Z"   ← Wrong! This is treated as ms.

The result looks vaguely correct (it’s a date, no parse error), so the bug often slips through code review. It manifests as:

The fix:

const date = new Date(ts * 1000);   // ts is seconds → multiply
// → "2025-01-01T00:00:00.000Z"   ← Right.

Or use a clear-named helper:

function dateFromUnixSeconds(s: number): Date {
  return new Date(s * 1000);
}
function dateFromUnixMs(ms: number): Date {
  return new Date(ms);
}

Detection rules

If you don’t know whether a number is seconds or milliseconds, the magnitude tells you (for any reasonable date in your lifetime):

< 10^11   →  seconds          (covers up to year ~5138)
< 10^14   →  milliseconds      (covers up to year ~5138)
< 10^17   →  microseconds
≥ 10^17   →  nanoseconds

The converter uses exactly this heuristic.

API design

If you’re designing an API and need to choose:

Common library defaults

When in doubt, check the docs — the defaults vary:

LibraryDefaultNotes
dayjs (JS)msWraps Date
luxon (JS)msSame
moment (JS)msSame
date-fns (JS)msWorks on Date directly
pendulum (Python)seconds (float)Wraps stdlib
arrow (Python)secondsSame
chrono (Rust)secondsUtc::now().timestamp()
time crate (Rust)secondsOffsetDateTime::now_utc().unix_timestamp()
Go stdlibsecondsUnix() returns int64 seconds
Joda-Time (Java)msWraps Instant

Try the tools