Unix Timestamp Explained: Epoch Seconds, Milliseconds and Timezones
Unix timestamps look like anonymous strings of digits, but they represent exact moments that can move safely between servers, databases, APIs and timezones. This guide explains the format, the common failure modes, and the conversions developers use every day.
A Unix timestamp is the number of elapsed seconds since 1 January 1970 at 00:00:00 UTC, a reference moment known as the Unix epoch. Instead of carrying a formatted date, language, or timezone, the value identifies one instant on a continuous timeline. That makes it useful for API responses, database columns, log entries, session expiration and distributed systems.
Paste seconds or milliseconds into the browser-based converter. It detects the unit automatically and shows UTC, local time, ISO 8601 and relative time without uploading the value.
Open Unix Timestamp ConverterWhat a Unix Timestamp Represents
The timestamp 0 is exactly the Unix epoch. Positive values represent moments after it; negative values represent moments before it. For example, 1704067200 represents 1 January 2024 at 00:00:00 UTC. Every correct implementation should convert that value to the same instant, regardless of the user's language or location.
A timestamp does not contain a timezone. It is not "in UTC" in the same sense that a formatted date can carry a UTC offset. It simply identifies an instant. UTC is the conventional reference used to translate that number into calendar fields. The same instant may display as 00:00 in London, 07:00 in Jakarta, or 19:00 on the previous day in New York.
Seconds vs Milliseconds
The original Unix format counts seconds, but JavaScript and many modern APIs count milliseconds. Confusing the two units is the most common timestamp bug. Current second values have 10 digits, while current millisecond values normally have 13 digits.
| Value | Likely unit | Approximate result | Common source |
|---|---|---|---|
1704067200 | Seconds | 2024-01-01 UTC | Unix, Python, PHP, SQL |
1704067200000 | Milliseconds | 2024-01-01 UTC | JavaScript, browser APIs |
1704067200000000 | Microseconds | 2024-01-01 UTC | Some databases and telemetry |
1704067200000000000 | Nanoseconds | 2024-01-01 UTC | Go and high-resolution systems |
Digit counting is a useful first check, not a mathematical guarantee. Historical millisecond values can have fewer than 13 digits, and dates far in the future can make second values longer than 10. Robust code should know the contract of its data source. Auto-detection is appropriate for an interactive utility, but a production API should document and enforce one unit.
How to Convert Epoch Time to a Date
Conversion starts by normalising the value to the unit expected by the runtime. JavaScript's Date constructor expects milliseconds, so a second timestamp must be multiplied by 1,000. Python's datetime.fromtimestamp expects seconds.
JavaScript
const epochSeconds = 1704067200;
const date = new Date(epochSeconds * 1000);
console.log(date.toISOString());
// 2024-01-01T00:00:00.000Z
Python
from datetime import datetime, timezone
epoch_seconds = 1704067200
date = datetime.fromtimestamp(epoch_seconds, tz=timezone.utc)
print(date.isoformat())
# 2024-01-01T00:00:00+00:00
SQL examples
-- PostgreSQL
SELECT to_timestamp(1704067200);
-- MySQL / MariaDB
SELECT FROM_UNIXTIME(1704067200);
-- SQLite
SELECT datetime(1704067200, 'unixepoch');
Database functions differ in their timezone behaviour. PostgreSQL returns a timezone-aware value when used with timestamptz; MySQL interprets and displays values according to the current session timezone; SQLite's datetime(..., 'unixepoch') returns UTC unless another modifier is applied. Treat the database documentation as part of the data contract.
How to Convert a Date to a Unix Timestamp
The reverse conversion subtracts the Unix epoch from a date and expresses the difference in seconds or milliseconds. The difficult part is rarely the arithmetic. It is deciding what timezone an input such as 2026-08-07 09:00 means.
- Require an explicit timezone or offset whenever input crosses a system boundary.
- Parse the date into an actual date-time object rather than manipulating text.
- Convert to UTC internally.
- Return seconds or milliseconds according to a documented contract.
// The Z makes the input explicitly UTC.
const date = new Date('2026-08-07T09:00:00Z');
const milliseconds = date.getTime();
const seconds = Math.floor(milliseconds / 1000);
A date string without Z or an offset such as +07:00 may be interpreted in local time. The same source code can then produce different timestamps on a developer laptop and a production server. ISO 8601 with an explicit offset avoids that ambiguity.
Unix Time and Timezones
Store the instant and choose the display timezone later. This separates two different concerns: when an event happened, and how a person wants to see it. For audit logs and machine-to-machine messages, UTC is normally the safest display. For appointments and recurring schedules, the named timezone can be part of the business data because daylight-saving rules matter.
A fixed offset such as +07:00 is not the same thing as a named timezone such as Asia/Jakarta. Jakarta currently uses UTC+7 throughout the year, but many regions change offset seasonally. Names from the IANA timezone database preserve those historical and future rules; offsets do not.
Five Common Timestamp Bugs
1. Mixing seconds and milliseconds
This creates the classic 1970 date or an implausibly distant future date. Name variables with their units—createdAtSeconds or expiresAtMs—and convert at system boundaries rather than throughout the codebase.
2. Parsing a timezone-free date string
2026-08-07 09:00 does not identify one instant until a timezone is supplied. Prefer ISO 8601 strings such as 2026-08-07T09:00:00+07:00.
3. Applying the timezone offset twice
A timestamp already identifies an absolute instant. Adding a local offset before passing it to a date library shifts the instant, and the library may then apply the offset again for display.
4. Using local time in signatures or expiration checks
JWT claims such as iat, nbf and exp use NumericDate: seconds since the Unix epoch. Compare those values against a UTC-based clock. Allow a small clock-skew tolerance where appropriate, but do not reinterpret them in local time.
5. Storing timestamps in a 32-bit signed integer
The maximum value is 2147483647, which represents 19 January 2038 at 03:14:07 UTC. One second later, a signed 32-bit counter overflows. Modern applications should use 64-bit integers or database date-time types with a documented range.
The Year 2038 Problem
The Year 2038 problem resembles the Year 2000 problem, but its cause is binary range rather than a two-digit year. Legacy Unix systems often store elapsed seconds in a signed 32-bit integer. One bit represents the sign, leaving 31 bits for positive values and a maximum of 2,147,483,647 seconds after the epoch.
Most current operating systems and application runtimes use 64-bit time values, whose practical range extends far beyond ordinary requirements. Risk remains in embedded devices, old file formats, network protocols and database schemas that explicitly chose a 32-bit integer. Audit the storage type, not merely the operating system.
When Unix Timestamps Are the Right Choice
- Comparing or sorting absolute instants across systems.
- Representing token expiration, cache lifetimes and event creation times.
- Sending compact machine-readable values through APIs.
- Recording logs where locale-specific formatting would create ambiguity.
They are less suitable for dates that are not instants. A birthday, billing month, or recurring "09:00 every Monday in Europe/Paris" carries calendar meaning that a bare epoch value cannot preserve. Use a date-only type or a local date-time plus an IANA timezone for those cases.
Frequently Asked Questions
Is Unix time always measured in seconds?
The original definition uses seconds, but many systems use milliseconds, microseconds or nanoseconds and still call the result a Unix timestamp. Always document the unit. Current values are usually 10 digits in seconds and 13 digits in milliseconds.
Does a Unix timestamp include a timezone?
No. It identifies an instant independently of timezone. A timezone is applied only when formatting that instant as a calendar date and clock time.
Why does my converted date show 1970?
The most likely cause is a unit mismatch: a seconds value was passed to a function that expects milliseconds. Multiply seconds by 1,000 before using JavaScript's Date constructor.
Can Unix timestamps represent dates before 1970?
Yes, using negative values, provided the language and storage type support them. Compatibility varies in older systems, especially on platforms with limited integer ranges.
Should an API return seconds or milliseconds?
Either can work if the contract is explicit and consistent. ISO 8601 strings are more readable, while integer timestamps are compact. Include the unit in documentation and preferably in field names where ambiguity is possible.
The TrenTyx converter accepts seconds and milliseconds, shows UTC and local representations, and converts dates back to epoch time. Processing stays in the browser tab.
Convert Unix TimestampRelated Tools and Guides
Published 7 August 2026 · Written and maintained by Ahmad Fawaid.