An API response returns 1709654400.
Can you tell what date that is at a glance? I couldn't. Every time, I'd google "Unix Timestamp converter" and paste it into some online tool. That tiny friction adds up, so I decided to build my own converter.
Try it out: timestamp.puremark.app — zero-click timestamp conversion, right in your browser.
I got it working, but not before stepping on 3 landmines in JavaScript's Date API.
Landmine 1: new Date(1709654400) Returns 1970
I started confidently. Just pass the timestamp to new Date().
const date = new Date(1709654400);
console.log(date.toISOString());
// => "1970-01-20T21:34:14.400Z"
- Way off.
The cause was simple: JavaScript's Date expects milliseconds, but Unix timestamps are in seconds. You need to multiply by 1000.
const date = new Date(1709654400 * 1000);
console.log(date.toISOString());
// => "2024-03-05T00:00:00.000Z"
But should users have to think about whether they're entering seconds or milliseconds? No. I implemented auto-detection by digit count: 10 digits = seconds, 13 digits = milliseconds.
function toMillis(input) {
if (/^\d{10}$/.test(input)) return Number(input) * 1000;
if (/^\d{13}$/.test(input)) return Number(input);
return NaN;
}
Three lines. But without them, every input becomes a guessing game.
Landmine 2: Hyphens and Slashes Parse Differently
Next, I added date-string-to-timestamp conversion. Type 2024-03-05, get the Unix timestamp. Should be simple.
console.log(new Date('2024-03-05').toISOString());
// => "2024-03-05T00:00:00.000Z" (UTC)
console.log(new Date('2024/03/05').toISOString());
// => "2024-03-04T15:00:00.000Z" (JST midnight = UTC previous day)
Same date, different separators, completely different results. Hyphens get parsed as UTC (ISO 8601), slashes get parsed as local time (implementation-dependent).
MDN says it clearly:
Parsing date strings with the
Dateconstructor is strongly discouraged due to browser differences and inconsistencies.
The lesson: never trust new Date() with non-ISO-8601 strings.
Landmine 3: The Timezone Display Maze
Once conversion worked, I wanted a timezone comparison table — "What time is this in Tokyo? New York? Berlin?"
My first attempt was getTimezoneOffset().
const offset = new Date().getTimezoneOffset();
console.log(offset); // JST: -540
The sign is inverted. JST is UTC+9, but getTimezoneOffset() returns -540 minutes (= -9 hours). Plus, it only returns the user's local timezone — you can't get arbitrary timezones with it.
The solution: Intl.DateTimeFormat.
const date = new Date('2024-03-05T10:00:00Z');
date.toLocaleString('en-US', {
timeZone: 'Asia/Tokyo',
hour12: false,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit'
});
// => "03/05/2024, 19:00:00"
Just pass an IANA timezone identifier to the timeZone option. No external libraries needed. I implemented a 10-timezone comparison table covering UTC, JST, EST, PST, CET, GMT, IST, CST, AEST, and BRT.
See it in action: timestamp.puremark.app shows your timestamp across 10 cities at a glance. Each row has a copy button for pasting into Slack or Jira.
Before / After
| Before | After | |
|---|---|---|
| Checking timestamps | Google → copy-paste to some online tool | Just open a browser tab. Auto-reads from clipboard |
| Seconds vs milliseconds | Count digits manually | Auto-detected. Don't even think about it |
| Date string parsing | Trust new Date(), get bitten by browser differences |
Know that non-ISO-8601 is unreliable |
| Timezones | Confused by getTimezoneOffset() sign |
Intl.DateTimeFormat with 10-city display |
All three landmines are "obvious once you know" but can cost you hours if you don't. Hope this article saves you that time.
Timestamp converter → timestamp.puremark.app
Top comments (0)