JavaScript Date.now(): Getting and Converting Unix Timestamps
A focused guide to JavaScript Date.now(): get the current Unix timestamp, convert seconds vs milliseconds, turn timestamps into Date objects, format with Intl, and avoid the common parsing traps.
How JavaScript stores time internally
Every JavaScript Date is internally a single 64-bit float representing milliseconds since the Unix epoch (January 1, 1970 00:00:00 UTC). This number is what Date.getTime() returns and what Date.now() returns. There is no timezone stored inside a Date — it is always a UTC millisecond count. Timezone information only matters when you format the date for display, which is why the same Date object can appear as Monday evening in Los Angeles and Tuesday morning in Tokyo. This post focuses on Date.now() and converting timestamps; for a broader walkthrough of every timestamp task in JavaScript, see the complete reference guide linked below.
Getting the current Unix timestamp
Use Date.now() for milliseconds and Math.floor(Date.now() / 1000) for seconds. Both are widely supported and require no imports. The important naming habit is to include the unit in the variable name: createdAtMs, expiresAtSeconds, or unixSeconds. Unit names prevent a future API consumer from guessing what a bare timestamp field means.
- Date.now() → 1700000000000 (milliseconds, 13 digits)
- Math.floor(Date.now() / 1000) → 1700000000 (seconds, 10 digits)
- +new Date() → same as Date.now() via unary coercion
- new Date().getTime() → same result, slightly more verbose
Date.now() vs performance.now()
Date.now() is for wall-clock timestamps: logging, API payloads, database fields, cache expiry, and anything that needs to line up with real calendar time. performance.now() is for measuring elapsed duration inside the current page or process. It is monotonic and high precision, but it is not a Unix timestamp and cannot be converted into a real date without an additional reference point.
- Use Date.now() when the value will be stored, sent to an API, or shown as a date
- Use performance.now() when measuring how long rendering, parsing, or a request took
- Do not store performance.now() in a database as event time
- Do not subtract two Date.now() values for security-sensitive timing; system clock changes can affect them
Converting a timestamp to a Date
The Date constructor accepts milliseconds. If your timestamp is in seconds (10 digits), multiply by 1000 before passing it in. Forgetting this is the single most common JavaScript timestamp mistake. A quick sanity check is the number of digits: current Unix seconds have 10 digits, current Unix milliseconds have 13 digits, and a Date constructor call should receive the 13-digit millisecond form.
- new Date(1700000000 * 1000) → Tue Nov 14 2023 22:13:20 UTC ✓ correct
- new Date(1700000000) → Tue Jan 20 1970 16:13:20 UTC ✗ missing × 1000
- new Date(1700000000 * 1000).toISOString() → '2023-11-14T22:13:20.000Z'
- new Date(1700000000 * 1000).toUTCString() → 'Tue, 14 Nov 2023 22:13:20 GMT'
Timezone-aware formatting with Intl
Use Intl.DateTimeFormat for locale- and timezone-aware output. It handles daylight saving time automatically and requires no external libraries. This is the safest built-in path for dashboards, admin tools, status pages, and user-facing timestamps because it lets you choose both the locale and the IANA timezone explicitly.
- new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }).format(date)
- date.toLocaleString('en-GB', { timeZone: 'Europe/London', hour12: false })
- date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
- new Intl.DateTimeFormat('en-CA', { timeZone: tz }).formatToParts(date) → array of {type, value} for custom layouts
Parsing date strings safely
Parsing is where JavaScript becomes surprising. ISO strings with an explicit Z or offset are safe because they identify one exact instant. Bare dates and informal strings are easier to read, but they often depend on browser rules or the runtime timezone. For API contracts, prefer ISO 8601 strings with a timezone or numeric Unix timestamps with the unit written into the field name.
- Safe: new Date('2026-05-19T14:30:00Z') — explicit UTC
- Safe: new Date('2026-05-19T10:30:00-04:00') — explicit offset
- Risky: new Date('05/19/2026') — locale-dependent and ambiguous
- Risky: new Date('2026-05-19 10:30') — not a strict ISO timestamp in all runtimes
Common JavaScript timestamp mistakes
- new Date(1700000000) instead of new Date(1700000000 * 1000) — lands in 1970, not 2023
- getMonth() returns 0–11, not 1–12 — always use date.getMonth() + 1 when displaying
- new Date('2024-01-01') parses as UTC midnight; new Date('2024/01/01') parses as local midnight
- Adding 86400000 ms for 'tomorrow' breaks at DST transitions — use setDate(d.getDate() + 1) instead
- Comparing Date objects with === always fails — compare their .getTime() values instead
Recommended JavaScript timestamp checklist
The simplest production pattern is to store one canonical instant and format it only at the edge. Keep timestamps in UTC, include units in names, and convert to a human-readable timezone only in the UI or reporting layer.
- Use Unix milliseconds for browser-only state and JavaScript Date construction
- Use Unix seconds when calling APIs that document Unix time in seconds
- Use ISO 8601 with Z or an explicit offset when humans may inspect payloads
- Use Intl.DateTimeFormat with an explicit timeZone for display
- Add tests around DST boundaries when local calendar dates matter
JavaScript timestamp FAQ
- Does Date.now() return seconds or milliseconds?
- Date.now() returns milliseconds since January 1, 1970 00:00:00 UTC. Divide by 1000 and use Math.floor() when an API expects Unix seconds.
- Why does new Date(1700000000) show 1970?
- The Date constructor expects milliseconds. 1700000000 is a seconds timestamp, so JavaScript reads it as only 1.7 billion milliseconds after the epoch. Use new Date(1700000000 * 1000).
- Does a JavaScript Date store a timezone?
- No. A Date stores a UTC millisecond count. The timezone is applied only when formatting with methods like toString(), toLocaleString(), or Intl.DateTimeFormat.
- How do I convert a Unix timestamp to a JavaScript Date?
- Pass milliseconds to the constructor: new Date(seconds * 1000) for a 10-digit seconds value, or new Date(ms) for a 13-digit milliseconds value. Forgetting the × 1000 is why a 2023 timestamp can render as 1970.