Date Epoch: The Complete Guide to Unix Time, Conversion, and Best Practices
Introduction
The date epoch (often called Unix time) is the backbone of time in software. It counts seconds from 00:00:00 UTC on January 1, 1970. This simple number powers logs, APIs, databases, and analytics. In this guide, you’ll learn exactly how the date epoch works, how to convert it, and how to use it safely across systems.
Featured Snippet (Quick Answer)
The date epoch, or Unix time, is the number of seconds since January 1, 1970, 00:00:00 UTC (ignoring leap seconds). To convert a human date to epoch, parse the date in UTC and divide by 1000 if you start from milliseconds. To convert epoch to a date, multiply by 1000 (if needed) and format in your target time zone.
AI Overview
Date epoch (Unix time) represents time as a single integer: seconds since 1970-01-01T00:00:00Z. It’s fast, compact, and easy to compare and sort. Use UTC for all storage and convert only at display time. Watch for milliseconds vs seconds, time zones, and 32‑bit overflow in older systems. This guide shows quick conversions, code examples for major languages and SQL, real-world use cases, common pitfalls, and best practices for reliable time handling.
Key Takeaways
- Date epoch = seconds since 1970‑01‑01T00:00:00Z (Unix epoch)
- Store in UTC; convert to local time only for display
- Know if your data uses seconds, milliseconds, or microseconds
- Use 64‑bit integers to avoid the Year 2038 problem
- ISO 8601 is best for human-readable interchange; epoch is best for storage and math
- Always document time zone, precision, and units in your API and schema
Table of Contents
What is date epoch?
The date epoch, commonly known as Unix time or POSIX time, is a simple counter. It tracks the number of seconds that have passed since the Unix epoch: 1970‑01‑01 00:00:00 UTC. Most systems ignore leap seconds, so the clock ticks evenly.
Two common units exist:
- Seconds: 1700000000
- Milliseconds: 1700000000000 (JavaScript Date.now())
Related formats:
- ISO 8601: 2026-04-12T08:30:00Z
- RFC 2822: Sun, 12 Apr 2026 08:30:00 +0000
Note: A negative epoch represents dates before 1970 (e.g., -31536000 for 1969).
Why it Matters
Time is hard. Locale, daylight saving, and calendars vary. The date epoch makes time math predictable:
- Sorting by time is a numeric sort
- Comparing durations is subtraction
- Cross-language and cross-DB compatibility is easy
- Storage footprint is small and index-friendly
From logs to JWT expirations, epoch time is a universal glue for time data.
Benefits
- Speed: Integers compare fast and index well
- Simplicity: One number, one timeline (UTC)
- Accuracy: Millisecond and microsecond support when needed
- Interoperability: Works across platforms, languages, and protocols
- Storage efficiency: Smaller than formatted strings
- Determinism: No daylight saving surprises in calculations
Step-by-Step Guide
1) Convert with ZenixTools (Fastest)
Use the ZenixTools Date Epoch Converter:
- Paste a human date or an epoch value
- Choose the correct unit (seconds or milliseconds)
- Select your target time zone
- Copy the converted value or formatted ISO string
Tip: Toggle UTC/local view to verify time zone handling.
2) Manual Conversion Basics
- Human date → epoch (seconds): parse UTC datetime, divide milliseconds by 1000, floor
- Epoch (seconds) → human date: multiply by 1000 to get milliseconds, then format
Formulas:
- seconds = floor(ms_since_epoch / 1000)
- ms_since_epoch = seconds * 1000
3) JavaScript
// Current epoch
const s = Math.floor(Date.now() / 1000); // seconds
const ms = Date.now(); // milliseconds
// From ISO to epoch seconds (UTC)
const iso = '2026-04-12T08:30:00Z';
const epochSec = Math.floor(new Date(iso).getTime() / 1000);
// From epoch seconds to Date
const d = new Date(epochSec * 1000);
// Format as ISO 8601 (UTC)
const isoOut = d.toISOString();
Warning: new Date() parses local time if you omit the Z; prefer explicit UTC.
4) Python
from datetime import datetime, timezone
# Now
epoch_sec = int(datetime.now(tz=timezone.utc).timestamp())
epoch_ms = int(datetime.now(tz=timezone.utc).timestamp() * 1000)
# ISO to epoch
iso = '2026-04-12T08:30:00Z'
epoch_sec_from_iso = int(datetime.fromisoformat(iso.replace('Z', '+00:00')).timestamp())
# Epoch to datetime (UTC)
dt = datetime.fromtimestamp(epoch_sec, tz=timezone.utc)
iso_out = dt.isoformat().replace('+00:00', 'Z')
5) Java
import java.time.*;
// Now
long sec = Instant.now().getEpochSecond();
long ms = Instant.now().toEpochMilli();
// ISO to epoch seconds
Instant inst = Instant.parse("2026-04-12T08:30:00Z");
long s = inst.getEpochSecond();
// Epoch to ZonedDateTime
ZonedDateTime zdt = Instant.ofEpochSecond(s).atZone(ZoneOffset.UTC);
6) PHP
// Now
$sec = time();
$ms = (int)round(microtime(true) * 1000);
// ISO to epoch seconds (UTC)
$dt = new DateTimeImmutable('2026-04-12T08:30:00Z');
$s = $dt->getTimestamp();
// Epoch to ISO
$iso = (new DateTimeImmutable('@' . $s))->setTimezone(new DateTimeZone('UTC'))->format(DateTime::ATOM);
7) Go
import (
"time"
)
// Now
sec := time.Now().Unix()
ms := time.Now().UnixMilli()
// ISO to epoch seconds
iso := "2026-04-12T08:30:00Z"
t, _ := time.Parse(time.RFC3339, iso)
s := t.Unix()
// Epoch to time
u := time.Unix(s, 0).UTC()
8) Ruby
require 'time'
sec = Time.now.to_i
ms = (Time.now.to_f * 1000).to_i
iso = '2026-04-12T08:30:00Z'
s = Time.parse(iso).to_i
utc_time = Time.at(s).utc
9) Bash / Shell
# Current epoch seconds (GNU date)
date +%s
# Epoch to human (UTC)
date -u -d @1700000000 '+%Y-%m-%dT%H:%M:%SZ'
# Human to epoch (UTC)
date -u -d '2026-04-12 08:30:00' +%s
Note: BSD/macOS date uses different flags; prefer Python or Node for portability.
10) SQL (PostgreSQL, MySQL)
PostgreSQL:
-- Now (seconds)
SELECT EXTRACT(EPOCH FROM NOW())::bigint;
-- Epoch to timestamp (UTC)
SELECT to_timestamp(1700000000 AT TIME ZONE 'UTC');
-- Timestamp to epoch seconds
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2026-04-12 08:30:00+00')::bigint;
MySQL/MariaDB:
-- Now (seconds)
SELECT UNIX_TIMESTAMP();
-- Epoch to timestamp (UTC)
SELECT FROM_UNIXTIME(1700000000);
-- Timestamp to epoch
SELECT UNIX_TIMESTAMP('2026-04-12 08:30:00');
11) Time Zones and DST
- Epoch is always UTC. It never “jumps” for DST.
- Display time by converting UTC to the user’s zone.
- Never store local time as epoch; store UTC and keep the user’s time zone separately.
Example (JS):
const s = 1700000000; // UTC seconds
tz = 'America/New_York';
const d = new Date(s * 1000);
// Use a library like Intl.DateTimeFormat with timeZone
ew Intl.DateTimeFormat('en-US', { timeZone: tz, dateStyle: 'medium', timeStyle: 'long' }).format(d);
12) Precision: s vs ms vs μs
- Seconds (s): compact; common in APIs and JWTs
- Milliseconds (ms): common in JavaScript and logs
- Microseconds (μs) or nanoseconds (ns): high-resolution tracing
Always label units in field names or docs, e.g., created_at_s, updated_at_ms.
Real World Examples
Logging and Monitoring
- Store event_time_ms for precise ordering
- Index on event_time for fast range scans
- Roll up metrics by bucketing: bucket = floor(epoch_s / 60) for per-minute stats
API Tokens and Security
- JWT exp uses epoch seconds
- Enforce clock skew tolerance (e.g., ±5 minutes) when validating
Databases and Warehouses
- Partition by date derived from epoch for faster queries
- Use BIGINT for epoch values to avoid overflow
Analytics and Growth
- A/B tests: compute durations as end_s - start_s
- Funnel steps: sort by epoch, group by user_id
Scheduling and Queues
- Delayed jobs: run_at_s > now_s
- Backoff algorithms: next_try_s = now_s + delay_s
IoT and Edge
- Offline devices buffer measurements with epoch_ms
- On reconnect, server reorders by epoch_ms, not by arrival time
Blockchain and Finance
- Trades timestamped with epoch_ms for sequencing
- Beware leap-second assumptions; use monotonic clocks for latency, epoch for wall time
Common Mistakes
- Confusing seconds and milliseconds (values differ by 1000x)
- Parsing local time as UTC (or vice versa)
- Using 32‑bit integers for epoch (Year 2038 problem)
- Ignoring time zone offsets when formatting for users
- Rounding incorrectly (floor vs round) for boundaries
- Assuming epoch accounts for leap seconds (POSIX usually ignores them)
- Mixing UTC storage with local display without clear labels
Warnings:
- Warning: If your epoch ends with three extra zeros unexpectedly, you likely fed ms to a seconds API.
- Warning: Never store user local time as epoch without capturing the original time zone.
Best Practices
- Store in UTC as an integer (BIGINT for s/ms) and document units
- Use ISO 8601 with Z or explicit offset for human-readable fields
- Prefer 64‑bit integers everywhere; audit old code for 32‑bit time_t
- Normalize inputs to UTC before conversion
- Validate ranges: reject absurd dates (e.g., < 1970 or far future) when appropriate
- Index epoch columns for range queries
- In APIs, name fields with units: created_at_s, created_at_ms
- Provide both epoch and ISO 8601 in public APIs for clarity
- For analytics, bucket with integer math to avoid DST issues
- Keep servers time-synced (NTP) to trust “now”
Notes:
- Note: POSIX time excludes leap seconds. Use TAI or GPS time only if you have specialized needs.
- Note: Git, Redis, and many systems rely on epoch time—follow their conventions in integrations.
Expert Tips
- Cross-language parity: write unit tests that assert known conversions across JS, Python, and SQL
- Rounding: use floor for “start of” ranges, and ceil for “end of” ranges minus one unit
- Performance: prefer integers over TIMESTAMP when scanning huge datasets
- Compression: epoch deltas compress well; consider delta encoding in columnar stores
- Observability: log both epoch_ms and an ISO field for human-debugging
- Localization: do not pre-format dates on the server for multi-region apps; send epoch/ISO and localize on the client
- Backfills: when backfilling historical data, store source_time_zone in a meta column
- Data governance: document time semantics (UTC, units, precision) in your schema README
Comparison Table
| Format | Example | Pros | Cons | Size | Best Use |
|---|
| Epoch seconds | 1700000000 | Compact; fast; easy math | 1s granularity; unit confusion | 8B | APIs, auth, queues |
| Epoch ms | 1700000000000 | High precision; JS native | Larger; still unit confusion | 8B | Logs, analytics, UI timing |
| ISO 8601 UTC | 2026-04-12T08:30:00Z | Human-friendly; unambiguous | Slower to parse; larger storage | ~20B | Data exchange, audit trails |
| RFC 2822 | Sun, 12 Apr 2026 08:30:00 +0000 | Readable emails/HTTP headers | Locale-ish; parsing variance | ~29B | Legacy protocols, headers |
| Local string | 04/12/2026 04:30 AM EDT | User-facing | Ambiguous; DST problems | varies | UI only (never store) |
Frequently Asked Questions
- What is the date epoch in simple terms?
- It’s a count of seconds since 1970‑01‑01 00:00:00 UTC, used to represent time as a single integer.
- Why do developers prefer epoch time?
- It’s compact, fast to compare, easy to sort, and avoids daylight saving confusion in calculations.
- Is epoch in seconds or milliseconds?
- Both exist. Many APIs use seconds; JavaScript commonly uses milliseconds. Always document units.
- How do I get the current epoch in JavaScript?
- Seconds: Math.floor(Date.now() / 1000); Milliseconds: Date.now().
- How do I convert epoch to a readable date?
- Multiply seconds by 1000 (if needed), create a date/time object, then format in your target time zone.
- Does epoch handle leap seconds?
- Standard POSIX time ignores leap seconds. Time moves as if they don’t exist.
- How do time zones affect epoch?
- Epoch is always UTC. Convert to local time only when displaying to users.
- What is the Year 2038 problem?
- 32‑bit signed integers overflow around 2038‑01‑19. Use 64‑bit integers (BIGINT) to avoid it.
- Can I represent dates before 1970 with epoch?
- Yes. They’re negative numbers (e.g., -31536000 for 1969‑01‑01).
- Which is better: ISO 8601 or epoch?
- Use epoch for storage and math; use ISO 8601 for human-readable interchange. Many APIs provide both.
- How do I convert in SQL?
- PostgreSQL: to_timestamp(s) and EXTRACT(EPOCH FROM ts). MySQL: FROM_UNIXTIME(s) and UNIX_TIMESTAMP(ts).
- Why is my time 1000x off?
- You likely mixed milliseconds and seconds. Check the unit your function expects.
- How do I display local time for a user?
- Store UTC epoch. On display, convert to the user’s time zone using a time zone-aware library.
- Should I store microseconds or nanoseconds?
- Only if you truly need that precision (tracing, HFT). Otherwise, milliseconds or seconds are enough.
- How do JWT exp and iat work?
- They use epoch seconds. Validate with a small clock skew allowance between systems.
Conclusion
The date epoch gives you a simple, universal way to store and compare time. Keep everything in UTC, document units clearly, and watch for seconds vs milliseconds. With the right patterns, you’ll avoid time bugs, scale your data, and keep users happy. Master the date epoch once, and time handling across your stack becomes far easier.
Call To Action
Convert, format, and debug timestamps instantly with ZenixTools. Try the Date Epoch Converter, verify time zones, and generate ISO 8601 strings in one place. Build faster and ship with confidence—no more time bugs.
Internal Link Suggestions
- ZenixTools Date Epoch Converter
- ZenixTools Time Zone Converter
- ZenixTools ISO 8601 Formatter
- ZenixTools Cron Expression Tester
- ZenixTools UUID & ULID Generator
External References