By Docify

Unix Seconds vs Milliseconds: UTC vs Local

• 6 min read

POSIX time (IEEE Std 1003.1) is seconds since 1970-01-01T00:00:00Z and ignores leap seconds — each day is 86400 of those seconds. JavaScript Date stores milliseconds: new Date(n * 1000) vs new Date(n). toISOString() is UTC. Date.parse treats date-only YYYY-MM-DD as UTC midnight and a T date-time without an offset as local. Docify does not auto-detect the unit. Nothing is uploaded.

The same decimal is not one instant. The unit (seconds vs milliseconds) and the display (UTC vs the browser zone) are separate choices. The live Unix timestamp converter makes both explicit and does not infer them.

Seconds since the Epoch are not JavaScript Date

POSIX: 86400-second days, leap seconds ignored

IEEE Std 1003.1 (“Seconds Since the Epoch”) relates a UTC civil name to an integer with a formula that treats every day as exactly 86400 seconds. Inserted UTC leap seconds are not added to the count. That value is not TAI and is not a table of leap-second insertions. Negative years relative to 1970 are left undefined by the POSIX formula; JavaScript Date still accepts some pre-epoch instants as negative milliseconds.

1700000000 → 2023-11-14T22:13:20.000Z

ECMA-262: one Number, in milliseconds

A JavaScript Date holds a time value: milliseconds from the same epoch, also ignoring leap seconds. Date.now() and getTime() return that millisecond count. new Date(n) treats n as milliseconds, so Unix seconds must be multiplied first. The representable range is about ±100 million days from the epoch; values outside that become Invalid Date. IEEE-754 integers stay exact only through 2^53 − 1 milliseconds — far beyond ordinary Unix seconds, but relevant for nanosecond-scale integers pasted by mistake.

Digit count is not a unit

1700000000 in both units

Ten digits often look like “seconds” and thirteen like “milliseconds,” but the same integer means different instants:

seconds: 1700000000 → 2023-11-14T22:13:20.000Z
milliseconds: 1700000000 → 1970-01-20T15:06:40.000Z

Unix seconds gain an 11th digit on 2286-11-20T17:46:40Z. Fractional seconds, leading zeros, and negative timestamps also break a length check. Docify’s Seconds toggle calls new Date(n * 1000); Milliseconds calls new Date(n). Convert is a button, not as-you-type.

UTC display vs local display vs parse

toISOString, toUTCString, toLocaleString

The stored instant does not have a time zone. toISOString() always writes UTC with a Z suffix. toUTCString() is the UTC HTTP-date style string (the GMT label there is UTC). toLocaleString() formats in the host zone from Intl.DateTimeFormat().resolvedOptions().timeZone. That is a display choice, not an IANA picker and not NTP.

Date.parse: date-only UTC, date-time local

ECMA-262’s date-time string format (a simplified ISO 8601) is the portable input. When the offset is absent, date-only forms (YYYY, YYYY-MM, YYYY-MM-DD) are UTC; date-time forms (YYYY-MM-DDTHH:mm:ss) are local. Locale phrases are engine-specific. Prefer a Z or a numeric offset.

2026-08-20 vs 2026-08-20T00:00:00

Those two strings are not the same instant unless the browser zone is UTC. The converter uses Date.parse only. Unix seconds out are Math.floor(ms / 1000); milliseconds are getTime().

Neighbor clocks this page does not implement

JWT NumericDate, Y2038, TAI

RFC 7519 iat / exp / nbf are Unix seconds (NumericDate). The JWT decoder shows those numbers as new Date(n * 1000).toISOString() and does not compare them to the clock. A signed 32-bit time_t overflows at 2147483647 (2038-01-19T03:14:07Z); JavaScript Number is not that type. This site is not TAI, not a leap-second smear, not microseconds or nanoseconds, and not an NTP client.

Convert Unix seconds or milliseconds

Explicit unit. UTC ISO and local display. Nothing is uploaded.

Use Unix Timestamp Converter →

FAQ

Are Unix timestamps seconds or milliseconds?
POSIX “seconds since the Epoch” (IEEE Std 1003.1) is an integer count of seconds since 1970-01-01T00:00:00Z that ignores leap seconds — every calendar day is 86400 of those seconds. JavaScript Date stores a time value in milliseconds (ECMA-262). Date.now() and getTime() are milliseconds. Docify does not guess the unit from digit count: Seconds calls new Date(n * 1000); Milliseconds calls new Date(n).
Why does 1700000000 look like 2023 in one unit and 1970 in the other?
1700000000 seconds is 2023-11-14T22:13:20.000Z. The same integer as milliseconds is only 1,700,000 seconds after the epoch: 1970-01-20T15:06:40.000Z. Digit-count heuristics (10 digits = seconds, 13 = milliseconds) fail for fractions, negatives, and values past 2286-11-20 when Unix seconds themselves gain an 11th digit. Pick the unit explicitly.
Is toISOString() UTC? What about YYYY-MM-DD?
toISOString() is always UTC with a Z suffix. toUTCString() is the UTC HTTP-date style string. The Local row uses toLocaleString() in the browser zone from Intl.DateTimeFormat().resolvedOptions().timeZone. Date.parse of a date-only YYYY-MM-DD (no time, no offset) is UTC midnight. A date-time without an offset (2026-08-20T00:00:00) is local. Prefer a Z or numeric offset.
Does this page convert JWT iat / exp or apply leap seconds?
No. RFC 7519 NumericDate is Unix seconds, but this guide and the converter do not decode tokens or compare claims to the clock. POSIX time is not TAI and not a leap-second table: inserted UTC leap seconds are ignored. There is no IANA zone picker and no NTP sync.

Related