Epoch Converter in JavaScript
Convert Unix timestamps to dates and back in JavaScript: the idiomatic code, the gotchas, and a live converter.
How do you convert a Unix timestamp to a Date in JavaScript?
Use new Date(ts * 1000) for a 10-digit seconds timestamp, since the Date constructor expects milliseconds. Going back, Date.now() returns milliseconds and Math.floor(Date.now() / 1000) gives whole seconds. Forgetting the * 1000 is the classic bug: the date renders as January 1970 plus a few weeks.
const ts = 1777010400; // 10 digits means seconds const d = new Date(ts * 1000); // Date wants milliseconds console.log(d.toISOString()); // 2026-04-24T06:00:00.000Z
const ms = Date.now(); // milliseconds since epoch const sec = Math.floor(Date.now() / 1000); // whole seconds, floored console.log(ms, sec);
JavaScript is the odd one out: milliseconds everywhere
Nearly every backend convention counts epoch in seconds, but JavaScript standardized on milliseconds. Date.now(), the Date constructor, getTime(), and performance timestamps all speak 13-digit milliseconds. The moment a JS frontend talks to a Python or Go backend, someone has to multiply or divide by 1000, and that conversion is where timestamps break. A quick sanity check: 10 digits is seconds, 13 is milliseconds. If new Date(ts) gives you February 1970, you passed seconds; if a backend rejects your exp claim as absurdly far in the future, you sent milliseconds.
Date renders in local time by default
A Date object stores a UTC instant internally, but almost every way of looking at it lies to you. console.log(d), d.toString(), and d.getHours() all render in the machine's local timezone, so the same instant prints differently on your laptop and in CI. When you need the actual UTC value, reach for toISOString() or the getUTC* accessors. One more sharp edge: Date.now() / 1000 produces a fractional value like 1777010400.123, and APIs that validate whole-second timestamps, JWT iat and AWS request signing among them, will reject it. Always Math.floor when an API wants seconds.
Frequently asked
- Why does new Date(timestamp) show a 1970 date?
- You passed epoch seconds to a constructor that expects milliseconds, so a 2026 timestamp is read as about 20 days after January 1, 1970. Multiply the value by 1000 first: new Date(1777010400 * 1000) gives the correct 2026 date.
- How do I get the current Unix timestamp in seconds in JavaScript?
- Math.floor(Date.now() / 1000). The floor matters: the division leaves a fractional millisecond remainder, and signed requests or JWT claims that expect an integer will fail validation on a value like 1777010400.123.
- Why does the same Date print different times on different machines?
- Date stores UTC internally but toString() and getHours() render in the local timezone of whatever machine runs the code. Use toISOString() or the getUTC* methods when you need output that is identical everywhere.
More in this series
// The subscription desk
The Inference Report
The weekly briefing for AI engineers: model releases, pricing moves, benchmarks, and the news that changes what you should build with and what it costs. Every Tuesday, 5-minute read. No fluff.
Join AI engineers who stopped overpaying for tokens. Unsubscribe anytime.