Skip to content
LeedyBox
Support

Unix Timestamps Explained

A Unix timestamp is a single number for a moment in time. It is easy to store and compare, but units, time zones and text formats cause many conversion mistakes.

What Unix Time Is

Unix time (also called epoch time or POSIX time) counts the seconds since 1970-01-01 00:00:00 UTC, the Unix epoch. 0 is the epoch itself, 1700000000 is 2023-11-14 22:13:20 UTC, and negative values are moments before 1970: -1 is 1969-12-31 23:59:59 UTC.

The number contains no time zone: it describes the same moment everywhere, which makes it practical for storing, sorting and comparing events.

Unix time ignores leap seconds: every day has exactly 86,400 seconds. When a leap second is added to UTC, systems repeat a second or spread it over a longer period ("smearing"), so a difference across a leap second is one second shorter than the time that physically elapsed.

Seconds, Milliseconds, Microseconds or Nanoseconds?

Many systems count in smaller units, and the number does not say which. The same moment can appear as four very different numbers:

Unit 2023-11-14 22:13:20 UTC Digits (2001–2286) Often seen in
Seconds 1700000000 10 date +%s, many APIs, JWT exp claims
Milliseconds 1700000000000 13 JavaScript Date.now(), Java System.currentTimeMillis()
Microseconds 1700000000000000 16 Some databases and logging systems
Nanoseconds 1700000000000000000 19 Go UnixNano(), Python time.time_ns()

Counting digits is the quickest check for current dates. The LeedyBox converter uses the same idea: values up to 1011 are read as seconds, up to 1014 as milliseconds, up to 1017 as microseconds and larger values as nanoseconds. This rule of thumb fails for dates far from today, so check the unit when a result looks odd.

Precision matters as well. JavaScript numbers represent integers exactly only up to 253 (about 9 × 1015), so a nanosecond value such as 1700000000123456789 loses its last digits when it is parsed as a normal number. Keep such values as strings or use BigInt; the converter does this internally. To read a token's exp claim, decode it with the Base64, URL & JWT tool.

Time Zones and Daylight Saving Time

To show a timestamp as a date and clock time, you need a time zone. UTC is the reference; local time adds an offset such as +09:00 in Seoul or −05:00 in New York in winter.

Prefer IANA time zone names such as Asia/Seoul or America/New_York over fixed offsets and abbreviations: a name carries the zone's history and daylight saving rules, while an abbreviation such as CST stands for several zones. The rules come from the time zone database, which changes several times a year, and browsers, operating systems and languages ship their own copies, so results for past or future dates can differ.

Daylight saving time creates two awkward cases when you convert a local time to a timestamp:

  • Gap: when clocks move forward, some local times do not exist. In America/New_York, 2026-03-08 02:30 is skipped because clocks jump from 02:00 to 03:00.
  • Overlap: when clocks move back, some local times occur twice. 2026-11-01 01:30 happens once in EDT (UTC−04:00) and again an hour later in EST (UTC−05:00).

Libraries resolve these cases differently. The LeedyBox converter uses the later valid time in a gap (03:30 here) and the earlier occurrence in an overlap, and explains this in a note. Scheduled jobs face the same issue; see How to Read Cron Expressions.

ISO 8601, RFC 3339 and HTTP Dates

When a moment has to be readable, write it in ISO 8601 or its stricter internet profile, RFC 3339:

2023-11-14T22:13:20Z
2023-11-15T07:13:20+09:00
2023-11-14T22:13:20.500Z

Z means UTC. With Z or an offset the string is unambiguous. A string without either, such as 2023-11-14T22:13:20, is a local time in an unknown zone, and parsers disagree on how to read it.

HTTP headers such as Last-Modified and Expires use an older format derived from the email date format (RFC 2822, now RFC 5322), written in GMT: Tue, 14 Nov 2023 22:13:20 GMT.

The Year 2038 Problem

Many older systems store Unix time in a signed 32-bit integer. Its largest value, 2147483647, is 2038-01-19 03:14:07 UTC. One second later the counter overflows to -2147483648, which reads as 1901-12-13 20:45:52 UTC. Current operating systems and languages mostly use 64-bit time values, which cover hundreds of billions of years, but 32-bit fields still appear in embedded devices, file formats, database columns and network protocols. If your code or data stores seconds in 32 bits, plan the change early and test dates after 2038 now.

Timestamps in Code and Databases

JavaScript works in milliseconds:

Math.floor(Date.now() / 1000);                  // current Unix time in seconds
new Date(1700000000 * 1000).toISOString();      // "2023-11-14T22:13:20.000Z"
Date.parse("2026-10-03T09:00:00+09:00") / 1000; // 1790985600

Python's time.time() returns seconds as a float. Pass tz=timezone.utc, otherwise fromtimestamp() returns the computer's local time without a zone:

import time
from datetime import datetime, timezone

int(time.time())                                     # seconds
datetime.fromtimestamp(1700000000, tz=timezone.utc)  # 2023-11-14 22:13:20+00:00
datetime.fromisoformat("2026-10-03T09:00:00+09:00").timestamp()  # 1790985600.0

In SQL the functions differ by database:

-- PostgreSQL
SELECT extract(epoch FROM now());   -- seconds, with a fraction
SELECT to_timestamp(1700000000);    -- timestamp with time zone
-- MySQL
SELECT UNIX_TIMESTAMP();
SELECT FROM_UNIXTIME(1700000000);   -- in the session time zone

For storage, a few habits prevent most problems:

  • Store moments that have happened in UTC, either in a timestamp-with-time-zone column or as a 64-bit integer whose unit is part of the column name, such as created_at_ms.
  • Store future local events, such as a meeting at 09:00 in Seoul, as the local date and time plus the IANA zone name, and calculate the timestamp when needed, so a later rule change does not move the meeting.
  • Do not mix units in one column; a wrong unit is off by a factor of 1,000 or more.

Frequently Asked Questions

Why does my timestamp convert to a date in 1970?

The value was probably read in the wrong unit: seconds read as milliseconds land in January 1970, and milliseconds read as seconds land tens of thousands of years in the future. Count the digits or choose the unit in the converter.

Does a Unix timestamp depend on my time zone?

No. It counts seconds from a fixed moment in UTC. Only the date and time shown for it depend on the time zone.

Can Unix time represent a leap second?

No. Unix time treats every day as 86,400 seconds, so a UTC time such as 23:59:60 has no timestamp of its own.