Unix Time Explained: Epoch Timestamps from 1970 to 2038
Updated November 2026
A Unix timestamp such as 1767225600 counts the seconds since a fixed starting point, the Unix epoch: 00:00:00 UTC on 1 January 1970. That particular number is exactly midnight UTC on 1 January 2026. Because a timestamp is just a number with no time zone attached, it is the most common way for computers to store and exchange moments in time. This guide explains how to read timestamps, how to convert them correctly in common languages, and the edge cases that cause real bugs: milliseconds, time zones, leap seconds and the year 2038.
How Unix time works
Unix time goes up by one every second, and at any given instant it has the same value everywhere on Earth. Some reference points:
| Timestamp | Date and time (UTC) | Note |
|---|---|---|
0 | 1970-01-01 00:00:00 | The epoch |
86400 | 1970-01-02 00:00:00 | One day is 86,400 seconds |
-86400 | 1969-12-31 00:00:00 | Negative values are dates before 1970 |
1000000000 | 2001-09-09 01:46:40 | The first 10-digit timestamp |
1767225600 | 2026-01-01 00:00:00 | Used in the examples below |
2000000000 | 2033-05-18 03:33:20 | |
2147483647 | 2038-01-19 03:14:07 | Largest signed 32-bit value |
In Unix time every day is exactly 86,400 seconds long, which keeps arithmetic simple: 1,767,225,600 ÷ 86,400 = 20,454, so 1 January 2026 is day 20,454 after the epoch, and adding 7 × 86,400 to a timestamp moves it exactly one week forward. Local clock time is another matter, as the section on time zones explains.
Seconds, milliseconds and smaller units
The classic Unix convention counts seconds, but many systems use finer units. The number of digits usually gives it away: for dates between 2001 and 2286, a timestamp in seconds has 10 digits.
| Digits | Unit | Typical sources | 1 January 2026, 00:00 UTC |
|---|---|---|---|
| 10 | seconds | Unix shells, PHP, most databases, JWT exp claims | 1767225600 |
| 13 | milliseconds | JavaScript Date.now(), Java System.currentTimeMillis() | 1767225600000 |
| 16 | microseconds | some APIs, logs and analytics systems | 1767225600000000 |
| 19 | nanoseconds | Go UnixNano(), Python time.time_ns() | 1767225600000000000 |
Mixing up units is a classic bug. Read milliseconds as seconds and you get a date tens of thousands of years in the future; read seconds as milliseconds and you land in January 1970. If a converted date shows 1970, suspect this first. The Unix Timestamp Converter detects the unit from the number of digits automatically.
Time zones and UTC
A timestamp has no time zone; it marks an instant. Time zones only come in when you display it. The timestamp 1767225600 is:
- 1 January 2026, 00:00 in London (UTC+0 in winter)
- 1 January 2026, 08:00 in Shanghai (UTC+8)
- 1 January 2026, 09:00 in Seoul and Tokyo (UTC+9)
- 31 December 2025, 19:00 in New York (UTC−5 in winter)
Good practice follows from this:
- Store and send instants in UTC, as a Unix timestamp or an ISO 8601 string ending in
Zor an offset. - Convert to local time only at the edges: when you show a date to a person or read one from them.
- Use IANA time zone names such as
Asia/SeoulorAmerica/New_Yorkrather than fixed offsets or abbreviations. A name carries the region’s daylight saving rules and their history; an offset such as −05:00 is right for New York only part of the year. - For future events in local time, such as a meeting every Monday at 9:00 in Berlin, store the local time and the zone name rather than a precomputed timestamp. Governments change daylight saving rules, and a timestamp calculated today could end up an hour off.
To compare a time across cities, the Time Zone Converter applies daylight saving automatically. To count the days between two dates or add days to a date, use the Date Calculator.
Converting timestamps in code
All examples use 1767225600, which is 2026-01-01 00:00:00 UTC.
JavaScript
| Task | Code |
|---|---|
| Now, in seconds | Math.floor(Date.now() / 1000) |
| Timestamp → ISO string | new Date(1767225600 * 1000).toISOString() gives "2026-01-01T00:00:00.000Z" |
| Show in a time zone | new Date(1767225600 * 1000).toLocaleString("en-US", { timeZone: "Asia/Seoul" }) |
| Date string → timestamp | Date.parse("2026-01-01T09:00:00+09:00") / 1000 gives 1767225600 |
JavaScript dates work in milliseconds, so multiply by 1,000 on the way in and divide on the way out. Also, new Date("2026-01-01") (a date alone) is read as UTC midnight, while new Date("2026-01-01T00:00") (a date and time without an offset) is read as local time. Include Z or an offset whenever you mean a specific instant.
Python
| Task | Code |
|---|---|
| Now, in seconds | time.time() (a float) |
| Timestamp → UTC datetime | datetime.fromtimestamp(1767225600, tz=timezone.utc) |
| Timestamp → named zone | datetime.fromtimestamp(1767225600, tz=ZoneInfo("Asia/Seoul")) |
| Datetime → timestamp | datetime(2026, 1, 1, tzinfo=timezone.utc).timestamp() gives 1767225600.0 |
The imports are from datetime import datetime, timezone and from zoneinfo import ZoneInfo (Python 3.9 and later). Avoid “naive” datetimes without tzinfo: calling .timestamp() on one assumes the computer’s local time zone, and datetime.utcfromtimestamp(), which returns a naive value, is deprecated since Python 3.12. On Windows, zoneinfo also needs the tzdata package (pip install tzdata), because Windows does not include the IANA time zone database.
SQL
| Database | Timestamp → date | Date → timestamp |
|---|---|---|
| PostgreSQL | to_timestamp(1767225600) | EXTRACT(EPOCH FROM TIMESTAMPTZ '2026-01-01 00:00:00+00') |
| MySQL | FROM_UNIXTIME(1767225600) | UNIX_TIMESTAMP('2026-01-01 00:00:00') |
| SQLite | datetime(1767225600, 'unixepoch') | unixepoch('2026-01-01 00:00:00') |
PostgreSQL’s to_timestamp returns a timestamptz, displayed in the session’s TimeZone setting. MySQL’s FROM_UNIXTIME and UNIX_TIMESTAMP both use the session time zone, so the same query can return different results on two servers; run SET time_zone = '+00:00' first if you want UTC. SQLite works in UTC; unixepoch() needs SQLite 3.38 or later, and older versions can use strftime('%s', '2026-01-01 00:00:00'), which returns text.
Shell
| Task | Linux (GNU date) | macOS (BSD date) |
|---|---|---|
| Now, in seconds | date +%s | date +%s |
| Timestamp → date (UTC) | date -u -d @1767225600 | date -u -r 1767225600 |
| Date → timestamp | date -u -d '2026-01-01 00:00:00' +%s | date -u -j -f '%Y-%m-%d %H:%M:%S' '2026-01-01 00:00:00' +%s |
Leap seconds
UTC occasionally inserts a leap second to stay in step with the Earth’s slightly irregular rotation. Twenty-seven have been added since 1972, the most recent at 23:59:60 UTC on 31 December 2016. Unix time pretends they do not exist: every day has exactly 86,400 seconds, so during a leap second the Unix clock repeats or holds a second, and some large operators instead “smear” the extra second over many hours. For most software this is invisible. Where it matters, in measuring short intervals, use a monotonic clock such as performance.now() in JavaScript or time.monotonic() in Python instead of wall-clock time. In 2022 the General Conference on Weights and Measures voted to effectively abolish leap seconds by 2035.
The year 2038 problem
Many older systems store Unix time as a signed 32-bit integer, whose largest value is 2,147,483,647, or 03:14:07 UTC on Tuesday 19 January 2038. One second later the counter wraps around to −2,147,483,648, which such a system reads as 20:45:52 UTC on 13 December 1901.
Modern 64-bit operating systems and languages use 64-bit timestamps, which will not overflow for about 292 billion years. The risk lies in old or embedded devices, file formats and database columns that still use 32 bits. MySQL’s TIMESTAMP column type, for instance, ends at 2038-01-19 03:14:07 UTC, while DATETIME does not have this limit. Software that calculates dates far ahead, such as 15-year loan schedules or long-lived certificates, can hit the limit well before 2038 arrives.
ISO 8601: the readable alternative
When a time must be readable by people as well as programs, use ISO 8601 or its stricter internet profile, RFC 3339. The fields run from the largest unit to the smallest:
2026-01-01T00:00:00Z: UTC, whereZmeans a zero offset2026-01-01T09:00:00+09:00: the same instant written as Seoul or Tokyo time2026-01-01: a calendar date without a time
Because the fields run from year to second, ISO 8601 strings with the same format and offset sort correctly as plain text, which makes them handy in file names and logs. Avoid formats such as 01/02/2026, which is 2 January in the United States but 1 February in most of Europe.
Related tools
- Unix Timestamp Converter – convert timestamps in seconds, milliseconds, microseconds or nanoseconds to dates and back.
- Time Zone Converter – compare a date and time across cities, with daylight saving handled.
- Date Calculator – count days between dates or add days, weeks and months.