
2026-08-17
How to Convert a Unix Timestamp to a Date in JavaScript
Convert a Unix timestamp to a date in JavaScript with new Date(timestamp * 1000). The seconds-vs-milliseconds rule, time zone formatting and common fixes.
To convert a Unix timestamp to a date in JavaScript, multiply it by 1000 and pass it to the Date constructor: new Date(timestamp * 1000). The multiplication is the whole trick — Unix timestamps count seconds since 1 January 1970, but JavaScript's Date counts milliseconds. Skip the * 1000 and your 2026 date silently becomes January 1970.
const timestamp = 1786000000;
const date = new Date(timestamp * 1000);
console.log(date.toISOString());
// "2026-08-06T07:06:40.000Z"
That's the answer. The rest of this guide covers the parts that actually bite people: telling seconds from milliseconds, formatting the result for humans, and converting back the other way. If you just need a quick one-off check, paste the number into our free Unix Timestamp Converter — no code required.
Why does my timestamp show 1970 in JavaScript?
Because the value is in seconds and new Date() expects milliseconds. This is the single most common bug in timestamp code, and it fails quietly:
new Date(1786000000).toISOString();
// "1970-01-21T16:06:40.000Z" ← wrong, forgot the * 1000
Twenty-one days after the epoch instead of the year 2026. No error, no warning — just a wrong date sitting in your database.
The reason is that the two worlds disagree on units. Unix time — used by C, Python, PHP, MySQL, most REST APIs and every server log file — counts seconds. The ECMAScript specification defines a JavaScript Date as a number of milliseconds since the same 1970 epoch, which is why Date.now() returns a 13-digit number. Anything crossing that boundary needs a factor of 1000. (For the backstory on why 1970 is the zero point at all, see why Unix time starts in 1970.)
Seconds or milliseconds? How to tell which you have
Count the digits. For any date in the current era the answer is unambiguous:
| Digits | Unit | Example | Means |
|---|---|---|---|
| 10 | Seconds | 1786000000 | 6 Aug 2026 |
| 13 | Milliseconds | 1786000000000 | 6 Aug 2026 |
| 16 | Microseconds | 1786000000000000 | 6 Aug 2026 |
Ten digits means seconds and needs the * 1000. Thirteen digits is already milliseconds — pass it straight to new Date(). If you're handling both (say, from two different APIs), normalise defensively:
function toDate(value) {
const n = Number(value);
// 13+ digits is already milliseconds
return new Date(n < 1e11 ? n * 1000 : n);
}
The 1e11 threshold works because 100,000,000,000 seconds lands in the year 5138 — far beyond anything a real seconds-based timestamp will contain, and far below any millisecond timestamp from the last 50 years.
How do I format a timestamp into a readable date?
new Date() returns a Date object, not text. How you turn it into a string matters more than most people expect, because the default output is machine-shaped:
const date = new Date(1786000000 * 1000);
date.toISOString();
// "2026-08-06T07:06:40.000Z" ← always UTC, good for storage and APIs
date.toString();
// A long local-time string that varies by machine — avoid for output
For anything a person reads, use toLocaleString() with an explicit locale and time zone. Being explicit is what makes the output predictable instead of "whatever the server happens to be set to":
const date = new Date(1786000000 * 1000);
date.toLocaleString('en-GB', {
timeZone: 'UTC',
dateStyle: 'full',
timeStyle: 'short',
});
// "Thursday, 6 August 2026 at 07:06"
date.toLocaleString('en-GB', {
timeZone: 'Asia/Karachi',
dateStyle: 'full',
timeStyle: 'short',
});
// "Thursday, 6 August 2026 at 12:06"
date.toLocaleString('en-US', {
timeZone: 'America/New_York',
dateStyle: 'medium',
timeStyle: 'short',
});
// "Aug 6, 2026, 3:06 AM"
One timestamp, three different wall-clock readings — because a timestamp is a single instant, and the time zone is applied only at display time. That's a feature, not a bug: store the number, format at the edge. If you need to compare the same moment across zones without writing code, our Time Zone Converter does exactly this.
How do I get the current Unix timestamp in JavaScript?
Use Math.floor(Date.now() / 1000). Date.now() gives milliseconds, so divide by 1000 and floor the result:
// Current time as a Unix timestamp (seconds)
const now = Math.floor(Date.now() / 1000);
// A specific date as a Unix timestamp (seconds)
const ts = Math.floor(new Date('2026-08-06T07:06:40Z').getTime() / 1000);
// 1786000000
Two details worth getting right:
- Use
Math.floor(), notMath.round(). Rounding can push you a full second into the future, which breaks "not valid before" comparisons and JWT expiry checks. - Include the
Z(or a+05:00style offset) when parsing a date string.new Date('2026-08-06T07:06:40Z')is unambiguously UTC;new Date('2026-08-06 07:06:40')is interpreted in the browser's local zone, so identical code produces different timestamps on different machines.
Common timestamp mistakes, and what to do instead
| Mistake | What happens | Fix |
|---|---|---|
new Date(seconds) | Date lands in Jan 1970 | new Date(seconds * 1000) |
Date.now() sent to a seconds-based API | Timestamp ~1000× too large | Math.floor(Date.now() / 1000) |
Parsing "2026-08-06 07:06:40" | Result depends on the machine's zone | Use ISO format with Z |
Math.round() when converting to seconds | Occasionally one second ahead | Math.floor() |
Formatting with toString() | Output differs per server and browser | toLocaleString() with explicit timeZone |
| Storing formatted text in the database | Zone information is lost forever | Store the timestamp or a UTC ISO string |
That last row is the one that costs the most later. Store the instant; format on the way out.
How do I show a live updating clock?
The same conversion powers any "current time" display. Read the clock, format it, repeat once a second:
setInterval(() => {
const seconds = Math.floor(Date.now() / 1000);
const label = new Date(seconds * 1000).toLocaleTimeString('en-GB', {
timeZone: 'UTC',
hour12: false,
});
document.getElementById('clock').textContent = label;
}, 1000);
For a full walkthrough — the HTML, the styling and handling the one-second drift properly — follow our step-by-step tutorial on building a digital clock in JavaScript.
Frequently asked questions
Does new Date(timestamp * 1000) apply my local time zone?
No. The Date object stores a single UTC instant; the time zone appears only when you format it. toISOString() always prints UTC, while toLocaleString() uses the browser's zone unless you pass an explicit timeZone option. To understand what the underlying number represents, read what is a Unix timestamp.
Can JavaScript handle timestamps from before 1970?
Yes. Negative timestamps represent moments before the epoch, and they work normally: new Date(-86400 * 1000) returns 31 December 1969. JavaScript's Date spans roughly ±8.64 × 10¹⁵ milliseconds around 1970 — about 273,790 years in each direction. Anything outside that range returns Invalid Date.
Is JavaScript affected by the Year 2038 problem?
No. The 2038 problem hits systems that store timestamps in a signed 32-bit integer, which overflows at 2147483647 seconds — 19 January 2038, 03:14:07 UTC. JavaScript stores time as a 64-bit floating point number of milliseconds, so it sails past 2038 without issue. You can still receive a broken value from a 32-bit backend, so the fix belongs on that side.
How do I calculate the difference between two timestamps? Subtract them. Two timestamps in seconds give a difference in seconds — divide by 86,400 for whole days. For calendar-aware date math that respects month lengths and leap years, our Days Between Dates Calculator is more reliable than raw arithmetic.
The rule is short enough to memorise: seconds in Unix, milliseconds in JavaScript, * 1000 in between. Get that one factor right and the rest of the Date API stops being mysterious. To sanity-check any number you run into — in a log file, a JWT payload or a database column — paste it into the Unix Timestamp Converter and see the real date instantly.