DD
DevDash
javascriptwebdevprogrammingbeginners

Convert Unix Timestamp to Date in JavaScript (And Back)

Convert Unix Timestamp to Date in JavaScript (And Back)

Unix timestamps are everywhere -- API responses, database records, log files, JWT tokens. Converting between timestamps and human-readable dates in JavaScript is straightforward, but there is one gotcha that catches everyone at least once.

The One Thing You Must Know

Unix timestamps are in seconds. JavaScript Date uses milliseconds.

// Unix timestamp (seconds since Jan 1, 1970)
const unixTimestamp = 1711036800;

// WRONG -- this gives you a date in 1970 new Date(unixTimestamp); // Thu Jan 20 1970 ...

// RIGHT -- multiply by 1000 new Date(unixTimestamp * 1000); // Thu Mar 21 2024 ...

If your date is showing up in January 1970, you forgot to multiply by 1000. If it is showing a date thousands of years in the future, you multiplied a millisecond timestamp that did not need it.

Quick check: If the number has 10 digits, it is seconds. If it has 13 digits, it is milliseconds.

function toDate(timestamp) {
  // Auto-detect seconds vs milliseconds
  if (timestamp < 1e12) {
    return new Date(timestamp * 1000);
  }
  return new Date(timestamp);
}

Unix Timestamp to Date

Basic Conversion

const timestamp = 1711036800;
const date = new Date(timestamp * 1000);

console.log(date.toISOString()); // "2024-03-21T16:00:00.000Z" console.log(date.toLocaleDateString()); // "3/21/2024" (varies by locale) console.log(date.toLocaleTimeString()); // "4:00:00 PM" (varies by locale)

Formatted Output with Intl.DateTimeFormat

Intl.DateTimeFormat is the modern, built-in way to format dates. No libraries needed:

const timestamp = 1711036800;
const date = new Date(timestamp * 1000);

// US format new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', timeZoneName: 'short' }).format(date); // "March 21, 2024 at 04:00 PM UTC"

// ISO-like format new Intl.DateTimeFormat('sv-SE', { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date); // "2024-03-21"

// Relative time const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }); const diffDays = Math.round((date - new Date()) / (1000 60 60 * 24)); rtf.format(diffDays, 'day'); // "342 days ago" (depends on current date)

Specific Timezone

const timestamp = 1711036800;
const date = new Date(timestamp * 1000);

// Display in a specific timezone new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false }).format(date); // "03/21/2024, 12:00"

// Tokyo time new Intl.DateTimeFormat('en-US', { timeZone: 'Asia/Tokyo', dateStyle: 'full', timeStyle: 'long' }).format(date); // "Friday, March 22, 2024 at 1:00:00 AM JST"

Date to Unix Timestamp

Current Time

// Method 1: Date.now() returns milliseconds
const msTimestamp = Date.now();          // 1711036800000
const unixTimestamp = Math.floor(Date.now() / 1000);  // 1711036800

// Method 2: getTime() const date = new Date(); const unix = Math.floor(date.getTime() / 1000);

// Method 3: Unary + operator const unix2 = Math.floor(+new Date() / 1000);

Specific Date

// From a date string
const unix = Math.floor(new Date('2024-03-21T16:00:00Z').getTime() / 1000);
// 1711036800

// From components (month is 0-indexed!) const unix2 = Math.floor(new Date(2024, 2, 21, 16, 0, 0).getTime() / 1000); // Note: month 2 = March

// Start of today const startOfDay = Math.floor( new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000 );

Watch out for month indexing. new Date(2024, 0, 1) is January 1, not February 1. This zero-indexed month is one of JavaScript's most notorious footguns.

Using Libraries

date-fns

import { fromUnixTime, getUnixTime, format } from 'date-fns';

// Timestamp to date const date = fromUnixTime(1711036800); console.log(format(date, 'yyyy-MM-dd HH:mm:ss')); // "2024-03-21 16:00:00"

// Date to timestamp const timestamp = getUnixTime(new Date('2024-03-21')); // 1711036800

date-fns is tree-shakeable -- you only import the functions you use. Bundle size for just fromUnixTime + format is around 7KB gzipped.

dayjs

import dayjs from 'dayjs';

// Timestamp to formatted date dayjs.unix(1711036800).format('YYYY-MM-DD HH:mm:ss'); // "2024-03-21 16:00:00"

// Date to timestamp dayjs('2024-03-21').unix(); // 1711036800

// With timezone plugin import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; dayjs.extend(utc); dayjs.extend(timezone);

dayjs.unix(1711036800).tz('America/New_York').format('YYYY-MM-DD HH:mm z'); // "2024-03-21 12:00 EDT"

dayjs is 2KB gzipped. It is the smallest full-featured date library.

Common Recipes

Time Elapsed Since Timestamp

function timeAgo(unixTimestamp) {
  const seconds = Math.floor(Date.now() / 1000) - unixTimestamp;

const intervals = [ { label: 'year', seconds: 31536000 }, { label: 'month', seconds: 2592000 }, { label: 'week', seconds: 604800 }, { label: 'day', seconds: 86400 }, { label: 'hour', seconds: 3600 }, { label: 'minute', seconds: 60 }, { label: 'second', seconds: 1 } ];

for (const interval of intervals) { const count = Math.floor(seconds / interval.seconds); if (count >= 1) { return ${count} ${interval.label}${count > 1 ? 's' : ''} ago; } } return 'just now'; }

timeAgo(Math.floor(Date.now() / 1000) - 3600); // "1 hour ago"

Validate a Timestamp

function isValidUnixTimestamp(ts) {
  const num = Number(ts);
  if (!Number.isFinite(num)) return false;

// Reasonable range: 1970-01-01 to 2100-01-01 const seconds = num < 1e12 ? num : num / 1000; return seconds >= 0 && seconds <= 4102444800; }

Timestamps in APIs

When building or consuming APIs, always document whether timestamps are seconds or milliseconds. The convention:

  • Most APIs (Unix standard): seconds (10 digits)
  • JavaScript/Java: milliseconds (13 digits)
  • Python time.time(): seconds (float with decimals)

If you need to quickly inspect or convert timestamps during development, devdash.io has an epoch converter that shows the conversion both ways and handles both seconds and milliseconds automatically. Handy for debugging API responses without writing throwaway code.

Summary

// Timestamp -> Date
new Date(unixSeconds * 1000)

// Date -> Timestamp Math.floor(date.getTime() / 1000)

// Current timestamp Math.floor(Date.now() / 1000)

// Format it new Intl.DateTimeFormat('en-US', options).format(date)

That covers 95% of timestamp work in JavaScript. The key is remembering the seconds-vs-milliseconds conversion, using Intl.DateTimeFormat for display formatting, and being explicit about timezones when they matter.

Related Tools

Want API access + no ads? Pro coming soon.