← Back to the tool

Unix Timestamp in JavaScript

Updated: May 2026

JavaScript's Date object works in milliseconds internally, while most Unix timestamps you receive from APIs and databases are in seconds. Keeping that one fact in mind prevents the majority of timestamp bugs in frontend and Node.js code.

Check a timestamp online →

Free · No upload · Instant

Getting the current timestamp

// Milliseconds (JavaScript native)
Date.now()                          // e.g. 1735689600000

// Seconds (Unix convention, most APIs)
Math.floor(Date.now() / 1000)       // e.g. 1735689600

// Equivalent alternatives
+new Date()                         // milliseconds
new Date().getTime()                // milliseconds
new Date().valueOf()                // milliseconds

Date.now() is the fastest and most readable option for getting the current timestamp. Avoid new Date().getTime() unless you need the Date object for something else.

Converting a timestamp to a Date object

const tsSeconds = 1735689600;        // from API
const tsMs      = 1735689600000;     // from JS native

// Always multiply seconds by 1000
const d1 = new Date(tsSeconds * 1000);
const d2 = new Date(tsMs);

console.log(d1.toISOString()); // "2025-01-01T00:00:00.000Z"
console.log(d2.toISOString()); // "2025-01-01T00:00:00.000Z"

Formatting a timestamp with Intl.DateTimeFormat

The Intl.DateTimeFormat API is the modern, locale-aware way to format dates in any timezone. It is available in all modern browsers and Node.js 12+.

const ts = 1735689600; // seconds
const ms = ts * 1000;

// Simple locale string
new Date(ms).toLocaleString('en-US', { timeZone: 'America/New_York' });
// → "12/31/2024, 7:00:00 PM"

// Full control with Intl
const fmt = new Intl.DateTimeFormat('en-GB', {
  timeZone: 'Europe/London',
  year: 'numeric', month: 'long', day: 'numeric',
  hour: '2-digit', minute: '2-digit', second: '2-digit',
  hour12: false
});
fmt.format(new Date(ms));
// → "1 January 2025 at 00:00:00"

// Relative time (e.g. "3 hours ago")
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const diffSeconds = Math.floor((Date.now() - ms) / 1000);
rtf.format(-Math.floor(diffSeconds / 86400), 'day');
// → "yesterday" or "5 months ago"

Parsing ISO 8601 strings safely

// Safe: ISO string with explicit Z (UTC)
new Date('2025-01-01T00:00:00Z').getTime() / 1000  // 1735689600

// Ambiguous: no timezone — treated as LOCAL in most engines
new Date('2025-01-01T00:00:00').getTime() / 1000    // varies by timezone!

// Ambiguous: date-only — treated as UTC in most engines
new Date('2025-01-01').getTime() / 1000             // 1735689600

// Always append Z to force UTC parsing from a date-only string
new Date('2025-01-01' + 'T00:00:00Z').getTime() / 1000

The ECMA-262 spec says that ISO 8601 date-only strings (YYYY-MM-DD) are parsed as UTC, while date-time strings without a timezone (YYYY-MM-DDTHH:mm:ss) are parsed as local. This is the single most common source of off-by-one-day bugs.

Utility functions worth keeping

const tsNow   = () => Math.floor(Date.now() / 1000);
const msToSec = ms => Math.floor(ms / 1000);
const secToMs = s  => s * 1000;
const isMs    = n  => Math.abs(n) > 1e10;  // heuristic: 13+ digits

function formatTs(tsSeconds, tz = 'UTC', locale = 'en-US') {
  return new Intl.DateTimeFormat(locale, {
    timeZone: tz,
    dateStyle: 'medium',
    timeStyle: 'medium'
  }).format(new Date(tsSeconds * 1000));
}

function addDays(tsSeconds, days) {
  return tsSeconds + days * 86400;
}

function startOfDay(tsSeconds, tz = 'UTC') {
  const d = new Date(tsSeconds * 1000);
  const parts = new Intl.DateTimeFormat('en-CA', {
    timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit'
  }).formatToParts(d);
  const p = Object.fromEntries(parts.map(x => [x.type, x.value]));
  return Math.floor(new Date(`${p.year}-${p.month}-${p.day}T00:00:00Z`).getTime() / 1000);
}

Node.js specifics

Node.js uses the same Date API as browsers. For high-resolution timing (profiling, benchmarks), use process.hrtime.bigint() which returns nanoseconds as a BigInt. For production timestamps you still want Math.floor(Date.now() / 1000).

When dealing with timezones in Node.js on a server, the server's system timezone affects toLocaleDateString() and similar methods. Always pass an explicit timeZone option to Intl.DateTimeFormat or use a library like date-fns-tz in complex workflows.