A Unix timestamp is the number of seconds that have elapsed since the Unix epoch — 1970-01-01T00:00:00Z (UTC) — and JavaScript represents the same moment as the number of milliseconds since that same instant, which is why the same value looks 1000× larger inside a JS engine than it does in a server log, an API payload, or a SQL row. The two representations coexist in nearly every system a web developer touches, and the gap between them is the single most common source of bad dates in JavaScript code: new Date() expects milliseconds, so a raw epoch-seconds value lands you in 1970 plus a tiny fraction of a second, and a milliseconds value mistakenly treated as seconds throws the parsed date out around the year 55000. This guide walks through the exact JavaScript calls that turn a Unix timestamp into ISO 8601, UTC, and local time, then covers the reverse path back to an epoch number. Every step is small enough to drop into a snippet, and the Unix Timestamp Converter lets you verify any value instantly in your browser.

how to convert unix timestamp to date in javascript
Convert Unix Timestamp to Date in JavaScript

Why JavaScript Uses Milliseconds Instead of Seconds

JavaScript's Date object was designed in the mid-1990s to mirror Java's java.util.Date, which stores time as a signed 64-bit integer count of milliseconds since the Unix epoch. That design decision became permanent: every modern JavaScript engine still treats time internally as a 64-bit floating-point count of milliseconds, which is why Date.now() returns milliseconds, why the Date constructor interprets a bare numeric argument as milliseconds, and why Performance.now() reports a sub-millisecond floating-point count of milliseconds rather than seconds.

Unix time itself, per the Wikipedia entry on Unix time, is defined as seconds since the epoch. So whenever JavaScript code talks to a server, decodes a JWT, reads a database column, or inspects a log line that uses seconds, the two units have to be reconciled at the boundary. The reconciliation rule is short and worth memorizing:

  • seconds to JavaScript: multiply by 1000
  • JavaScript to seconds: divide by 1000 and floor the result

That single line covers most of the bugs you will ever see in JavaScript time handling. The rest of the bugs come from forgetting which side of the boundary a value is on, or from passing a Date constructor an ambiguous string.

Convert Unix Timestamp to Date in JavaScript

The core path from a Unix timestamp to a human-readable date in JavaScript is five short steps. Run them in order and you will not accidentally land in 1970 or in the year 55000.

  1. Decide which unit you have. A Unix seconds timestamp for any date after September 2001 has 10 digits; a JavaScript milliseconds timestamp for the same moment has 13 digits. Count the digits before writing any code.
  2. If your value is in seconds, convert it to milliseconds before constructing the Date: const ms = unixSeconds * 1000;.
  3. Construct a Date object with that millisecond value: const d = new Date(ms);. Passing a bare number to the Date constructor is the only way to get a fully controlled, timezone-independent input.
  4. Choose an output format. For ISO 8601 call d.toISOString(); for a readable UTC string call d.toUTCString(); for the device's local timezone call d.toLocaleString().
  5. Verify the result by pasting the original seconds value into the Unix Timestamp Converter and comparing its ISO 8601 output against what your script produced.

Here is the worked example, using a single seconds value and checking the arithmetic once. Take 1700000000 seconds since the epoch. Multiply by 1000 to convert to JavaScript milliseconds: 1700000000 × 1000 = 1,700,000,000,000 ms. Pass that to new Date() and the resulting string methods return:

  • d.toISOString() → "2023-11-14T22:13:20.000Z"
  • d.toUTCString() → "Tue, 14 Nov 2023 22:13:20 GMT"
  • d.toLocaleString() → a value that depends on the device timezone, such as "11/14/2023, 10:13:20 PM"

Those three outputs are the same instant described three ways. The ISO string is the most portable, the UTC string is the most human-readable for cross-team logs, and the locale string is the one to show in a UI where the reader expects their own clock.

Compare the Four Output Views Side by Side

The Unix Timestamp Converter produces four views of the same moment, and each one maps cleanly onto a JavaScript method. The table below lines them up so it is obvious which method to call when you need a given shape.

View JavaScript call Timezone Sample for 1700000000
ISO 8601 d.toISOString() UTC (always) 2023-11-14T22:13:20.000Z
UTC string d.toUTCString() UTC (always) Tue, 14 Nov 2023 22:13:20 GMT
Local time d.toLocaleString() Device timezone varies by device
Relative (computed against Date.now()) Device timezone about 2 years ago

For sortability, storage, and shipping to a backend, ISO 8601 wins because every consumer parses it identically. For human display in a UI, local time is what readers expect because it shows them their own wall-clock reading. For audit trails, log lines, and any place where two developers in different cities need to compare values word-for-word, the UTC string keeps everyone on the same page. The relative view is best left for status feeds and notification copy, where "3 hours ago" carries more meaning than a full timestamp.

Go the Other Way: Date Back to Unix Timestamp

Just as often you need the reverse direction — turning an ISO 8601 string, a log line, or a user-typed date into the raw epoch number your API or database wants.

  1. Parse the input with new Date(dateString). Reliable inputs include ISO 8601 strings such as "2023-11-14T22:13:20Z", RFC 2822 strings, and a handful of engine-recognized formats.
  2. Call .getTime() to extract the milliseconds since the epoch as a number.
  3. If the destination API expects seconds, divide and floor the result: Math.floor(d.getTime() / 1000).
  4. If you need both at once, keep both values in scope: const ms = d.getTime(); const s = Math.floor(ms / 1000);.

Two pitfalls deserve a callout. First, new Date("2023-11-14") is parsed as UTC midnight, but new Date(2023, 10, 14) is parsed as local midnight — the same numbers, two different moments. Pass an ISO string with an explicit Z suffix when you want UTC. Second, avoid the Date constructor with two-digit years, omitted components, or locale-specific strings like "11/14/23" in any code that has to ship; engines disagree on those inputs, and the failure mode is silent.

Seconds Versus Milliseconds and the Year 2038 Problem

Two hazards are worth their own section because they are responsible for the bulk of timestamp bugs that survive code review.

The first is the seconds-versus-milliseconds mix-up. A current Unix timestamp in moments is a 10-digit number such as 1700000000. The same moment in JavaScript milliseconds is a 13-digit number such as 1700000000000. Mix them up and your "future date" lands in 1970, or the date parser walks forward into the year 55000. A small helper closes the gap by treating any value above 10^12 as milliseconds and anything below as seconds, which is the same heuristic the Unix Timestamp Converter uses to auto-detect the unit on paste:

function toMs(value) { return value > 1e12 ? value : value * 1000; }

The second hazard is the Year 2038 problem. Unix time stored in a signed 32-bit integer overflows at 03:14:07 UTC on 19 January 2038 and wraps back to 1901. The bug still lurks in legacy embedded firmware and a handful of older database systems, which is one reason it is worth eyeballing what a raw timestamp actually means before trusting it. Modern JavaScript engines, however, store time as a 64-bit double, which can represent dates well past the heat death of the sun, so client-side code is unaffected — but a timestamp that came from a 32-bit server clock can still arrive wrapped or wrong on the wire.

Test Any Timestamp in Your Browser

When you just need to know what a raw value means — say an exp claim pulled from a JWT, a database column copied from a query result, or a server log line — paste it into the Unix Timestamp Converter. The tool reads the digit count, lets you override the unit with a Seconds / Milliseconds selector if it guesses wrong, and shows all four views at once so you can sanity-check the result against what your JavaScript code is producing. Every conversion runs locally through the platform Date object and explicit UTC formatting, so nothing is uploaded and your data never leaves the page.

For server-side conversions on the same kind of value, the guide How to Convert a Unix Timestamp in SQL Queries covers the FROM_UNIXTIME and UNIX_TIMESTAMP calls in MySQL and the equivalent DATEADD / DATEDIFF patterns in SQL Server, so the boundary crossing between JavaScript and the database layer does not have to be re-derived from scratch.