Guide

Unix Timestamps in JavaScript and Python: The Complete Guide

2026-05-18 · 9 min read · Convert timestamps free →

A Unix timestamp is the number of seconds (or milliseconds) that have elapsed since 00:00:00 UTC on January 1, 1970 — a moment known as the Unix Epoch. It is the most widely used method for representing points in time in programming. Every API response, database record, log entry, and JWT token you encounter uses Unix timestamps. This guide explains exactly how to get, convert, compare, and format Unix timestamps in JavaScript and Python, covering every practical scenario.

Why Unix Timestamps?

The Unix timestamp has three properties that make it the preferred time representation in systems programming. First, it is a simple integer — trivial to store, compare, sort, and serialize. Comparing two timestamps to determine which is later is a single integer comparison. Storing a timestamp in a database requires just an integer column. Second, it is timezone-independent — Unix timestamps always represent UTC. Converting to local time happens only at display time, avoiding the entire class of bugs caused by storing times in local timezones. Third, it is universally supported — every programming language, database, and operating system has built-in support for Unix timestamps.

Getting the Current Unix Timestamp

JavaScript — seconds and milliseconds

// Milliseconds since epoch (most common in JavaScript)
const nowMs = Date.now();
// → 1746000000000

// Seconds since epoch (what most APIs and databases use)
const nowSec = Math.floor(Date.now() / 1000);
// → 1746000000

// Alternative approaches
const nowMs2 = new Date().getTime();
const nowMs3 = +new Date();  // coerce Date to number

// High-precision timestamp (microseconds, for performance measurement)
const preciseMs = performance.now();  // milliseconds since page load, not epoch

Python — seconds and milliseconds

import time
from datetime import datetime, timezone

# Seconds since epoch (float — includes sub-second precision)
now_sec = time.time()          # 1746000000.123456

# Integer seconds
now_int = int(time.time())     # 1746000000

# Milliseconds
now_ms = int(time.time() * 1000)   # 1746000000123

# Using datetime (explicit UTC — preferred for clarity)
now_utc = datetime.now(timezone.utc)
now_ts = int(now_utc.timestamp())  # 1746000000

Converting a Timestamp to a Human-Readable Date

JavaScript

const timestamp = 1746000000;  // seconds

// Create a Date object (JavaScript Date uses milliseconds)
const date = new Date(timestamp * 1000);

// Built-in formatting
date.toISOString();             // "2026-04-30T10:40:00.000Z"  (always UTC)
date.toLocaleDateString();      // "4/30/2026"  (local timezone)
date.toLocaleTimeString();      // "10:40:00 AM"
date.toLocaleString();          // "4/30/2026, 10:40:00 AM"

// Intl.DateTimeFormat — full control over formatting
const fmt = new Intl.DateTimeFormat('en-GB', {
  year: 'numeric', month: 'long', day: 'numeric',
  hour: '2-digit', minute: '2-digit', timeZoneName: 'short',
  timeZone: 'Europe/Brussels'  // ← Arun's timezone
});
fmt.format(date);
// "30 April 2026 at 12:40 CEST"

// Individual components
date.getUTCFullYear();  // 2026
date.getUTCMonth();     // 3  (0-indexed: April = 3)
date.getUTCDate();      // 30
date.getUTCHours();     // 10
date.getUTCMinutes();   // 40

Python

import time from datetime import datetime, timezone, timedelta timestamp = 1746000000 # UTC datetime dt_utc = datetime.fromtimestamp(timestamp, tz=timezone.utc) print(dt_utc) # 2026-04-30 10:40:00+00:00 print(dt_utc.isoformat()) # "2026-04-30T10:40:00+00:00" print(dt_utc.strftime('%d %B %Y %H:%M %Z')) # "30 April 2026 10:40 UTC" # Local timezone dt_local = datetime.fromtimestamp(timestamp) print(dt_local) # Specific timezone (requires zoneinfo, Python 3.9+) from zoneinfo import ZoneInfo brussels = ZoneInfo('Europe/Brussels') dt_brussels = datetime.fromtimestamp(timestamp, tz=brussels) print(dt_brussels.strftime('%d %B %Y %H:%M %Z')) # "30 April 2026 12:40 CEST"

Converting a Date to a Unix Timestamp

JavaScript

// From a date string
const date = new Date('2026-04-30T10:40:00Z');  // always include Z for UTC
const timestamp = Math.floor(date.getTime() / 1000);
// 1746000000

// From individual components (UTC)
const ts = Math.floor(Date.UTC(2026, 3, 30, 10, 40, 0) / 1000);
// Month is 0-indexed: April = 3

// From a local date (careful — depends on system timezone)
const localDate = new Date(2026, 3, 30, 12, 40, 0);  // noon local time
const localTs = Math.floor(localDate.getTime() / 1000);

Python

from datetime import datetime, timezone

# From an ISO 8601 string
dt = datetime.fromisoformat('2026-04-30T10:40:00+00:00')
timestamp = int(dt.timestamp())
# 1746000000

# From explicit UTC components
dt_utc = datetime(2026, 4, 30, 10, 40, 0, tzinfo=timezone.utc)
timestamp = int(dt_utc.timestamp())

# From a naive datetime (assumed local — avoid where possible)
dt_naive = datetime(2026, 4, 30, 12, 40, 0)
timestamp = int(dt_naive.timestamp())  # treats as local timezone

Seconds vs Milliseconds — Getting It Right

The single most common Unix timestamp bug is confusing seconds and milliseconds. Unix timestamps are traditionally in seconds. JavaScript's Date.now() returns milliseconds. Many modern APIs return milliseconds. Databases vary. The result: off-by-1000× errors that produce dates in 1970 or 55,000 years in the future.

// Detecting whether a timestamp is in seconds or milliseconds
function detectUnit(ts) {
  // Timestamps in seconds: roughly 1.7 billion in 2026
  // Timestamps in milliseconds: roughly 1.7 trillion in 2026
  return ts > 1e10 ? 'milliseconds' : 'seconds';
}

// Safe conversion — normalise to seconds
function toSeconds(ts) {
  return ts > 1e10 ? Math.floor(ts / 1000) : ts;
}

// Safe conversion — normalise to milliseconds
function toMilliseconds(ts) {
  return ts < 1e10 ? ts * 1000 : ts;
}

Check any timestamp instantly with ToolPry's Timestamp Converter — it auto-detects the unit and shows you the human-readable date immediately.

Common Timestamp Operations

Calculate the difference between two timestamps

// JavaScript
const start = 1746000000;
const end = 1746086400;
const diffSeconds = end - start;               // 86400
const diffMinutes = Math.floor(diffSeconds / 60);  // 1440
const diffHours = Math.floor(diffSeconds / 3600);  // 24
const diffDays = Math.floor(diffSeconds / 86400);  // 1

// Python
diff = end_ts - start_ts  # seconds
import datetime
delta = datetime.timedelta(seconds=diff)
print(delta.days)   # 1
print(delta.total_seconds())  # 86400.0

Add or subtract time

// JavaScript — add 7 days const oneWeekLater = timestamp + (7 * 24 * 60 * 60); // JavaScript — add 30 minutes const thirtyMinsLater = timestamp + (30 * 60); // Python — add 7 days using timedelta from datetime import datetime, timezone, timedelta dt = datetime.fromtimestamp(timestamp, tz=timezone.utc) future = dt + timedelta(days=7) future_ts = int(future.timestamp())

Check if a timestamp is in the past or future

// JavaScript
const isExpired = timestamp < Math.floor(Date.now() / 1000);
const isInFuture = timestamp > Math.floor(Date.now() / 1000);

// Python
import time
is_expired = timestamp < int(time.time())
is_in_future = timestamp > int(time.time())

Timestamps in Databases

PostgreSQL has a native TIMESTAMPTZ type that stores timestamps with timezone awareness. Prefer this over integers. EXTRACT(EPOCH FROM NOW()) returns the current Unix timestamp. TO_TIMESTAMP(1746000000) converts a Unix timestamp to a PostgreSQL datetime.

MySQL has a TIMESTAMP type (stores as seconds since epoch internally, displays as datetime) and a DATETIME type (no timezone awareness). Use UNIX_TIMESTAMP() to get the current Unix timestamp and FROM_UNIXTIME(1746000000) to convert back. MySQL's TIMESTAMP has a 2038 problem — it cannot represent dates after January 19, 2038 due to 32-bit integer overflow. Use BIGINT or DATETIME for dates beyond 2038.

MongoDB stores dates as 64-bit millisecond timestamps internally. The BSON Date type in drivers automatically handles conversion.

SQLite has no native date type — store Unix timestamps as INTEGER (seconds) and use SQLite's date functions: datetime(1746000000, 'unixepoch').

Frequently Asked Questions

What is the Unix timestamp for right now?

As of May 2026, the current Unix timestamp is approximately 1,746,000,000 seconds. Check the exact current value — updated live — at ToolPry's Timestamp Converter, which shows the live tick and lets you convert any timestamp in either direction.

What is the Year 2038 problem?

Systems that store Unix timestamps as signed 32-bit integers can only represent dates up to 03:14:07 UTC on January 19, 2038 — at which point the integer overflows and wraps to a large negative number, representing December 13, 1901. Modern systems use 64-bit integers for timestamps, which can represent dates up to approximately year 292 billion. If you are working with any legacy system that uses 32-bit timestamps (embedded systems, old databases, some MySQL configurations), be aware of this limitation for long-dated future timestamps.

Why does JavaScript's Date.now() return milliseconds?

It is a design decision from the early days of JavaScript intended to provide sub-second precision without using floating-point numbers. Unix tradition uses seconds, but JavaScript chose milliseconds as the native unit to allow precise timing in browser animations and event handling. This is why you always divide by 1000 when interfacing between JavaScript's Date.now() and Unix timestamp-based APIs, and multiply by 1000 when creating a Date object from a Unix timestamp in seconds.

How do I format timestamps for display in different timezones?

In JavaScript, use Intl.DateTimeFormat with the timeZone option — this is the correct, standards-based way. Pass the IANA timezone name (e.g., 'Europe/Brussels', 'America/New_York', 'Asia/Tokyo'). In Python 3.9+, use the zoneinfo module with the same IANA timezone names. Never hardcode UTC offsets (like +02:00) for timezone-aware display — offsets change with daylight saving time, but IANA timezone names automatically account for DST transitions.

Timestamps in APIs and Real-World Contexts

Unix timestamps appear in every layer of modern web development. Understanding how each system represents them prevents the class of bugs where a timestamp is off by 1000× or silently interpreted in the wrong timezone.

REST APIs typically return timestamps as Unix seconds in JSON integer fields, ISO 8601 strings in date fields, or Unix milliseconds in JavaScript-centric APIs. Always check the API documentation — and verify empirically with a known timestamp using ToolPry's Timestamp Converter to confirm the unit and format before building against it.

JWT tokens use Unix seconds for the exp, iat, and nbf claims. When a token appears expired, decode it and check the exp claim against the current time. Clock skew between servers is a common cause of spurious expiry errors.

Log files vary widely. Apache and Nginx use formatted date strings. Application logs from Node.js or Python apps often use Unix milliseconds or ISO 8601. syslog uses its own format. When aggregating logs from multiple sources, normalise all timestamps to UTC Unix milliseconds before processing.

Webhook payloads typically include a timestamp for replay attack prevention — you verify the webhook signature and reject payloads with timestamps older than five minutes. Always store and compare these in UTC seconds.

Handling Daylight Saving Time Correctly

Daylight saving time (DST) is the most common source of timestamp bugs in applications serving users across multiple timezones. The fundamental rule: always store timestamps in UTC Unix format and convert to local time only at display time.

// WRONG — storing local time string
const localTime = new Date().toLocaleString(); // "5/18/2026, 2:30:00 PM"
// This is ambiguous — which timezone? Does it include DST?

// RIGHT — store UTC Unix timestamp, convert at display
const timestamp = Math.floor(Date.now() / 1000); // store this

// Convert to user's local time only when displaying
const display = new Intl.DateTimeFormat('en', {
  dateStyle: 'full', timeStyle: 'long',
  timeZone: userTimezone  // e.g., 'Europe/Brussels'
}).format(new Date(timestamp * 1000));

// Python — same principle
import time
from datetime import datetime, timezone
from zoneinfo import ZoneInfo

# Store
stored_ts = int(time.time())

# Display
dt = datetime.fromtimestamp(stored_ts, tz=timezone.utc)
local_dt = dt.astimezone(ZoneInfo('Europe/Brussels'))
print(local_dt.strftime('%A, %B %d %Y at %H:%M %Z'))

DST transitions mean that some local times occur twice (when clocks go back) and some do not occur at all (when clocks go forward). UTC timestamps are always unambiguous — they map one-to-one to moments in time regardless of DST transitions. This is why every professional time handling guide gives the same advice: store UTC, display local.

Performance: When Timestamps Matter for Speed

For application performance monitoring, the millisecond resolution of Unix timestamps is sometimes not enough. JavaScript's performance.now() provides sub-millisecond timestamps relative to the page load. Python's time.perf_counter() provides the highest resolution timer available on the platform. These are for measuring durations, not for recording absolute times.

// JavaScript — measuring execution time
const start = performance.now();
heavyOperation();
const duration = performance.now() - start;
console.log(`Took ${duration.toFixed(2)}ms`);

// Python
import time
start = time.perf_counter()
heavy_operation()
duration = time.perf_counter() - start
print(f"Took {duration * 1000:.2f}ms")

Frequently Asked Questions

What is the current Unix timestamp?

As of May 2026, the current Unix timestamp is approximately 1,747,000,000 seconds. For the live value updated every second, use ToolPry's Timestamp Converter, which shows the ticking live timestamp and lets you convert any value in either direction between Unix and human-readable formats.

How do I convert a Unix timestamp to a specific timezone?

In JavaScript, use new Intl.DateTimeFormat('en', { timeZone: 'Europe/Brussels' }).format(new Date(timestamp * 1000)). In Python 3.9+, use datetime.fromtimestamp(ts, tz=ZoneInfo('Europe/Brussels')). Always use IANA timezone names (like 'Europe/Brussels', 'America/New_York') rather than UTC offsets — offsets change with DST, timezone names account for this automatically.

Why is my timestamp showing a date in 1970?

Your timestamp is in seconds but you are passing it to a function that expects milliseconds, or vice versa. JavaScript's new Date(timestamp) expects milliseconds — if you pass a seconds value like 1746000000, JavaScript interprets it as 1,746,000,000 milliseconds, which is in 2025. If you pass it as-is to a function expecting milliseconds and it shows 1970, your value is too small by a factor of 1000. Fix: new Date(timestamp * 1000) for seconds-based timestamps in JavaScript.

How do I format a timestamp as "2 hours ago" or "3 days ago"?

// JavaScript — using Intl.RelativeTimeFormat
function timeAgo(timestamp) {
  const seconds = Math.floor(Date.now() / 1000) - timestamp;
  const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
  if (seconds < 60) return rtf.format(-seconds, 'second');
  if (seconds < 3600) return rtf.format(-Math.floor(seconds / 60), 'minute');
  if (seconds < 86400) return rtf.format(-Math.floor(seconds / 3600), 'hour');
  return rtf.format(-Math.floor(seconds / 86400), 'day');
}
timeAgo(Date.now() / 1000 - 7200); // "2 hours ago"

Timestamps in Frontend Applications

Frontend applications have a specific challenge with timestamps: the user may be in any timezone, and the browser's local timezone is not always what you want for display. A booking application shows "3:00 PM" — but 3:00 PM where? A live event countdown shows "starts in 2 hours" — but that depends on knowing the event's timezone.

The correct pattern: store timestamps as UTC Unix seconds in your backend, transmit them in JSON as integers, and format them in the browser using Intl.DateTimeFormat with an explicit timezone option. For events that have a fixed local time regardless of the user's location (a concert in Brussels, a webinar at 9am Eastern), store the event's timezone alongside the timestamp and always display in that timezone. For notifications and relative times ("posted 3 hours ago"), use the user's local timezone.

The ToolPry Timestamp Converter handles both scenarios — paste any Unix timestamp and it shows the equivalent time in UTC and your local timezone simultaneously, with live auto-detection of seconds vs milliseconds.

// Production pattern for event display
function formatEventTime(utcTimestamp, eventTimezone, userLocale = 'en') {
  return new Intl.DateTimeFormat(userLocale, {
    weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
    hour: '2-digit', minute: '2-digit',
    timeZone: eventTimezone,       // e.g., 'Europe/Brussels'
    timeZoneName: 'short'          // shows CET / CEST etc.
  }).format(new Date(utcTimestamp * 1000));
}

formatEventTime(1746000000, 'Europe/Brussels', 'en-GB');
// "Thursday, 30 April 2026 at 12:40 CEST"