How to Convert Unix Timestamps: JavaScript, Python, SQL, and CLI Recipes
Practical developer recipes for bidirectionally converting 10-digit (seconds) and 13-digit (milliseconds) Unix epoch timestamps into UTC, ISO 8601, and local dates across JavaScript, Python, SQL, and terminal CLI tools.
Unix timestamp conversion is a daily task in debugging API payloads, audit logs, and database records. The core arithmetic is straightforward, but subtle bugs arise when languages expect milliseconds instead of seconds, when timezones silently shift display values, or when timestamps arrive as strings.
Bidirectional Conversion Matrix: Seconds vs. Milliseconds
| Format | Digits | Example (Epoch) | Converted Date (UTC) |
|---|---|---|---|
| Unix Seconds (POSIX) | 10 digits | 1700000000 | 2023-11-14T22:13:20Z |
| Unix Milliseconds | 13 digits | 1700000000000 | 2023-11-14T22:13:20.000Z |
| Unix Microseconds | 16 digits | 1700000000000000 | 2023-11-14T22:13:20.000000Z |
| Unix Nanoseconds | 19 digits | 1700000000000000000 | 2023-11-14T22:13:20.000000000Z |
If your integer has 10 digits (e.g. 1700000000), it measures seconds. If it has 13 digits (e.g. 1700000000000), it measures milliseconds. JavaScript's Date constructor requires milliseconds; passing a 10-digit number directly will output a date in January 1970.
ISO 8601 vs. Unix Epoch: When to Use Each in APIs
When designing REST and GraphQL payloads, developers frequently debate whether to serialize timestamps as raw integer epochs or standardized ISO 8601 strings (RFC 3339). Each format serves distinct operational trade-offs:
| Evaluation Metric | Raw Unix Epoch (Integer) | ISO 8601 / RFC 3339 (String) |
|---|---|---|
| Payload Size | Compact: 8 bytes in binary JSON (BSON/Protobuf) or 10-13 ASCII chars | Verbose: 20-24 bytes ('2026-09-05T12:00:00.000Z') |
| Human Observability | Poor: Requires a converter tool to read during log inspection | Excellent: Instantly human-readable in server logs and network tabs |
| Sorting & Indexing | Fast integer comparisons with zero string parsing overhead | Lexicographically sortable only if strictly formatted in UTC ('Z') |
| Timezone Ambiguity | Zero ambiguity: By definition strictly anchored to UTC | Can include explicit timezone offsets (e.g. '+02:00') |
A common architectural standard is storing timestamps internally as integers in database indexes, while serializing as ISO 8601 strings across public client-facing APIs.
JavaScript and TypeScript Recipes
The Date constructor accepts millisecond timestamps directly. For 10-digit second timestamps, multiply by 1000. For modern formatting without external libraries like Moment or Day.js, use Intl.DateTimeFormat or toISOString():
// 1. Convert 10-digit seconds to ISO 8601 UTC string
const epochSeconds = 1718000000;
const dateFromSeconds = new Date(epochSeconds * 1000);
console.log(dateFromSeconds.toISOString()); // "2024-06-10T06:13:20.000Z"
// 2. Convert 13-digit milliseconds to localized format with explicit IANA timezone
const epochMs = 1718000000000;
const formatted = new Intl.DateTimeFormat("en-US", {
timeZone: "America/New_York",
dateStyle: "full",
timeStyle: "long",
}).format(new Date(epochMs));
console.log(formatted); // "Monday, June 10, 2024 at 2:13:20 AM EDT"
// 3. Convert human date string to Unix Epoch (seconds & milliseconds)
const targetDate = new Date("2025-01-01T00:00:00Z");
const msTimestamp = targetDate.getTime(); // 1735689600000
const secTimestamp = Math.floor(targetDate.getTime() / 1000); // 1735689600Common Gotcha: JavaScript String Parsing Timezone Shift
One of the most insidious bugs in client-side JavaScript date conversion stems from how the Date constructor parses date-only strings versus date-time strings under ECMAScript rules:
// Date-only string: Parsed as UTC midnight per ECMAScript specification
const utcParsed = new Date("2026-09-05");
console.log(utcParsed.getTime()); // 1788566400000 (Consistent globally)
// Date-time string without 'Z': Parsed in the BROWSER'S LOCAL TIMEZONE!
const localParsed = new Date("2026-09-05T00:00:00");
// On a machine in New York (EDT, UTC-4), this yields 1788580800000 (+4 hours difference!)
console.log(localParsed.getTime());
// Always append 'Z' or use explicit ISO strings to guarantee deterministic epoch outputs:
const safeDate = new Date("2026-09-05T00:00:00Z");Python Recipes with zoneinfo and datetime
In Python 3.11+, use timezone-aware datetime objects with datetime.timezone.utc to avoid platform-dependent local timezone calculations:
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
# Epoch seconds to UTC datetime
epoch_sec = 1718000000
utc_dt = datetime.fromtimestamp(epoch_sec, tz=timezone.utc)
print(utc_dt.isoformat()) # 2024-06-10T06:13:20+00:00
# Convert to specific timezone (e.g. Asia/Tokyo)
tokyo_dt = utc_dt.astimezone(ZoneInfo("Asia/Tokyo"))
print(tokyo_dt.strftime("%Y-%m-%d %H:%M:%S %Z")) # 2024-06-10 15:13:20 JST
# Human date string to Epoch seconds
parsed_dt = datetime.fromisoformat("2025-01-01T00:00:00+00:00")
epoch_output = int(parsed_dt.timestamp()) # 1735689600SQL and Database Queries Postgres MySQL SQLite
Converting timestamps directly inside query filters enables index utilization and simplifies analytics queries without pulling raw data into application memory:
-- PostgreSQL: Convert epoch seconds to TIMESTAMP WITH TIME ZONE
SELECT to_timestamp(1718000000) AT TIME ZONE 'UTC';
-- PostgreSQL: Convert current timestamp to epoch seconds
SELECT EXTRACT(EPOCH FROM NOW())::BIGINT;
-- MySQL: Convert epoch seconds to DATETIME
SELECT FROM_UNIXTIME(1718000000);
-- MySQL: Convert DATETIME to epoch seconds
SELECT UNIX_TIMESTAMP('2025-01-01 00:00:00');
-- SQLite: Epoch seconds to formatted UTC text
SELECT datetime(1718000000, 'unixepoch');
-- SQLite: Current epoch seconds
SELECT strftime('%s', 'now');Command Line One Liners Bash jq PowerShell
Terminal pipelines often require on-the-fly epoch conversions when processing cURL responses or log streams:
# macOS / BSD date (convert epoch seconds to UTC)
date -r 1718000000 -u +"%Y-%m-%d %H:%M:%S UTC"
# GNU / Linux date
date -d @1718000000 -u +"%Y-%m-%d %H:%M:%S UTC"
# Parse timestamps directly inside jq stream
echo '{"created_at": 1718000000}' | jq '.created_at | todate'
# Windows PowerShell (epoch seconds to DateTime)
[DateTimeOffset]::FromUnixTimeSeconds(1718000000).UtcDateTimeEdge Cases Negative Timestamps and String Types
Timestamps prior to January 1, 1970 are represented by negative integers (e.g., -315619200 corresponds to 1960-01-01T00:00:00Z). Most modern standard libraries handle negative integers correctly, but legacy systems or unsigned integer schemas (UINT32) will overflow or fail validation. To understand why 1970 was established as the origin baseline, see our detailed guide on Unix Epoch Time Explained.
[NEED: real detail on how CoShareX formatter handles stringified timestamps vs integers, e.g. automatic trimming of quotation marks, scientific notation detection, or handling whitespace in batch inputs].
Code Formatter & Converter Suite
Validate, format, minify, and convert JSON, SQL, YAML, XML, and code dialects directly on your local machine.
Frequently Asked Questions
How do I convert a 10-digit Unix timestamp to a human date in JavaScript?
Multiply the 10-digit number by 1000 to convert seconds to milliseconds, then pass it to the Date constructor: new Date(timestamp * 1000).toISOString().
Why does my converted Unix timestamp show a different hour on different computers?
Unix timestamps represent a single universal moment in UTC. If you use methods like date.toString() or date.toLocaleTimeString(), the browser or OS formats the timestamp using the machine's local timezone. Use toISOString() or toUTCString() to enforce UTC representation.
How do I convert a date string back into a Unix timestamp?
In JavaScript, use Math.floor(new Date('2025-01-01T00:00:00Z').getTime() / 1000) to get seconds, or .getTime() for milliseconds. In Python, parse the string with datetime.fromisoformat() and call .timestamp().
Conclusion
Accurate timestamp conversion hinges on verifying unit precision (seconds vs. milliseconds) before parsing and explicitly preserving UTC across your transformation pipeline.
Related Articles
Unix Epoch Time Explained: The 1970 Genesis, Bitwise Y2K38 Overflow, and Leap Second Smearing
Technical systems analysis of Unix epoch time. Learn why January 1, 1970 was chosen, examine the bitwise signed 32-bit integer overflow of the Year 2038 bug, and discover how modern 64-bit systems and NTP leap smearing solve time measurement.
UtilitiesUnix Timestamps & Epoch Time: The Definitive Systems Reference Manual
Complete systems guide to Unix epoch time. Master unit scales (seconds to nanoseconds), cross-language parsing cheatsheets, ISO 8601 conversions, timezone normalization, and browser high-resolution timers.