What Unix time is#
A Unix timestamp counts seconds from a fixed starting point, the Unix epoch: 00:00:00 UTC on January 1, 1970. Because that starting point is defined in UTC, the same moment has the same number in Tokyo, Lagos and Lima. A time zone enters only when a program turns the number into a clock reading. POSIX, the standard behind Unix-style systems, calls it "seconds since the Epoch".
Computed with Node.js, these hold in every time zone:
| UTC moment | Unix time (seconds) | Why it matters |
|---|---|---|
| 1970-01-01T00:00:00Z | 0 | The epoch |
| 2000-01-01T00:00:00Z | 946684800 | The start of the year 2000 |
| 2001-09-09T01:46:40Z | 1000000000 | One billion seconds |
| 2026-10-09T00:00:00Z | 1791504000 | The day this guide was published |
| 2038-01-19T03:14:07Z | 2147483647 | Largest signed 32-bit value |
| 2106-02-07T06:28:15Z | 4294967295 | Largest unsigned 32-bit value |
Every UTC midnight is a multiple of 86,400: 1791504000 divided by 86,400 is exactly 20,735 days since the epoch. That works because Unix time counts every day as exactly 86,400 seconds.
Seconds or milliseconds: how to tell#
The traditional Unix timestamp counts seconds. JavaScript counts milliseconds: per MDN, Date.now() returns the milliseconds elapsed since the epoch. One instant therefore has two spellings, 1791504000 (10 digits) and 1791504000000 (13 digits).
From September 2001 to November 2286, seconds have 10 digits and milliseconds 13 (computed: 9999999999 seconds is November 20, 2286, 17:46:39 UTC). To convert, multiply seconds by 1,000 or divide milliseconds by 1,000. In JavaScript, new Date(1791536400 * 1000).toISOString() returns "2026-10-09T09:00:00.000Z".
How Unix time treats leap seconds#
It ignores them. POSIX defines "seconds since the Epoch" so that every day is exactly 86,400 seconds, and its rationale says leap seconds are ignored, which keeps time differences easy to compute. The latest leap second was added at the end of December 31, 2016, when UTC showed 23:59:60. Unix timestamps for that day run from 1483142400 to 1483228799, which is 86,400 values. The next, 1483228800, is 00:00:00 on January 1, 2017, so the extra second never gets a number.
The tz database lists 27 leap seconds since 1972, all additions (counted from its list, as of October 2026); How Your Phone Knows the Time: Atomic Clocks, Leap Seconds and the Network Behind Them explains why. A gap between two timestamps that straddles one is a second shorter than an atomic clock measured.
How a computer handles the leap second depends on its setup. Red Hat's guide to leap seconds and NTP describes five ways to handle one and notes that a Unix clock cannot show 23:59:60. Some systems repeat a second, so one timestamp can stand for two instants. Others spread the extra second over many hours, a leap smear that Google has long used for its public time servers.
The 2038 problem#
Some systems store Unix time in a signed 32-bit integer, with 31 bits for the value. The largest value is 2,147,483,647, which is 03:14:07 UTC on Tuesday, January 19, 2038. One second later the counter wraps to −2,147,483,648, which software reads as 20:45:52 UTC on December 13, 1901 (all computed). In New York the last good second is 22:14:07 EST on Monday, January 18, 2038; in Kolkata it is 08:44:07 on Tuesday, January 19.
Much current software uses 64-bit counters. A signed 64-bit count of seconds lasts about 292 billion years (computed), so the exposure sits in older code, file formats and small devices. According to the Linux kernel's documentation, the original timestamps in ext4 inodes are 32-bit signed seconds, and newer inodes add extra bits to extend the range. LWN reported in 2019 that the core kernel's conversion to 64-bit time was nearly complete, but old 32-bit code, file formats and devices that stay in service for decades remain the harder part. Whether a given product is safe depends on the product.
An unsigned 32-bit counter lasts until 06:28:15 UTC on February 7, 2106. As of October 2026, the 2038 limit is about 11 years away.
ISO 8601: the written form#
ISO 8601 is the international standard for writing dates and times as text: calendar dates, 24-hour clock times and UTC offsets. ISO 8601-1:2019 is the edition ISO's catalogue listed as current when this guide was researched, and a revision has been in preparation; check the catalogue for the latest status.
Take 2026-10-09T14:30:00+05:30. The date comes first, largest unit leading: year, month, day. T separates the date from the time. 14:30:00 is a 24-hour clock reading. +05:30 says the local clock is 5 hours 30 minutes ahead of UTC, as in India. For UTC itself you can write Z, spoken "Zulu" (UTC vs GMT: What Is the Difference and Which Should You Use?).
One instant can be written several ways (computed):
| Written as | Meaning |
|---|---|
2026-10-09T09:00:00Z | 09:00 UTC |
2026-10-09T14:30:00+05:30 | 14:30 in Kolkata |
2026-10-09T05:00:00-04:00 | 05:00 in New York (EDT, UTC-4) |
1791536400 | The same instant as Unix seconds |
Fractions of a second follow a decimal point; JavaScript's toISOString() writes milliseconds and a Z, as in 2026-10-09T09:00:00.250Z (for years outside 0 to 9999 it switches to an expanded year, and an invalid date throws an error). ISO 8601 also has ordinal dates (2026-282 is day 282 of the year) and week dates (2026-W41-5 is Friday of ISO week 41). The week year can differ from the calendar year: January 1, 2027, is 2026-W53-5 (computed; see ISO Week Numbers: How to Find the Week Number of Any Date).
RFC 3339, an IETF standard from 2002, is a profile of ISO 8601 for internet timestamps. It narrows the format to a calendar date, a full time and an explicit offset or Z, leaving out week and ordinal dates. It also defines -00:00 for a time whose UTC value is known but whose local offset is not, which is not the same claim as Z.
Store in UTC, show in local time#
Store the moment as UTC or a Unix timestamp, and convert to local time only when a person reads it. UTC has no gaps or repeats, so sorting and subtracting stay reliable. Keep the viewer's zone as an IANA name such as Asia/Kolkata, not an abbreviation: IST can mean India or Israel, and IST, CST, PST: Why Time Zone Abbreviations Mean Different Things explains why short labels collide. A fixed offset like -05:00 is not a zone either, because it cannot know when the clocks change (How Daylight Saving Time Works, Why It Exists and Who Still Uses It).
There is one exception. If an organizer books a meeting for 9:00 in New York next March, the intent is "9:00 on the New York clock", and governments can change daylight saving rules at short notice. Simon Willison argues that storing only the UTC value loses that intent, and recommends keeping the local time and the time zone. Compute the UTC instant when you need it.
Common bugs, with examples#
- Skipped and repeated hours. On March 8, 2026, New York clocks jump from 02:00 to 03:00, so 02:30 does not exist; Node.js on a New York clock turns
new Date(2026, 2, 8, 2, 30)into 03:30 EDT (computed). On November 1, 2026, 01:30 happens twice, at 1793511000 (EDT) and 1793514600 (EST). Python's PEP 495 calls these a gap and a fold. Those two local days last 23 and 25 hours, so "add 24 hours" and "same time tomorrow" differ. - Midnight in the wrong zone. MDN says a date-only string such as
"2026-10-09"is read as UTC, while a date-time without an offset such as"2026-10-09T00:00:00"is read as local time. On a New York clock,new Date("2026-10-09").getDate()returns 8, because UTC midnight is still the evening of October 8 there (computed). Add an explicit offset or Z. - Zero-based months. JavaScript's
getMonth()runs from 0 to 11, sonew Date(2026, 9, 9)is October 9 andnew Date(2026, 12, 1)rolls over to January 1, 2027 (computed). - Timing with the wall clock. MDN notes that
Date.now()can jump when the clock is adjusted, so useperformance.now()for durations. How Accurate Is Your Phone or Computer Clock? How to Check and Fix It covers clock drift.
Frequently asked questions
What is Unix time?
Unix time, also called epoch time or POSIX time, is the number of seconds since 00:00:00 UTC on January 1, 1970, not counting leap seconds. It is a single number for the whole world, converted into a local date and time only for display. At midnight UTC on October 9, 2026, it was 1791504000.
Is a Unix timestamp in seconds or milliseconds?
The traditional Unix timestamp counts seconds, while JavaScript's Date.now() counts milliseconds. From September 2001 to November 2286, seconds have 10 digits and milliseconds 13. Multiply seconds by 1,000 to convert: 1791536400 seconds is 1791536400000 milliseconds, or 09:00:00 UTC on October 9, 2026.
What does the Z at the end of a timestamp mean?
Z means the time is in UTC, an offset of zero, and is often spoken "Zulu" after the phonetic alphabet word for the letter. 2026-10-09T09:00:00Z equals 2026-10-09T09:00:00+00:00, and both name the same instant as 2026-10-09T14:30:00+05:30.
What is the Year 2038 problem?
Systems that store Unix time as a signed 32-bit integer cannot count past 2,147,483,647 seconds, which is 03:14:07 UTC on January 19, 2038. The next second wraps to a negative number that reads as December 13, 1901. The fix is 64-bit time, which the Linux kernel and many programs already use. The remaining risk is older 32-bit software, file formats and long-lived embedded devices.
Should I store timestamps in UTC or local time?
Store the moment in UTC, as an ISO 8601 string ending in Z or as a Unix timestamp, and convert to local time only for display, using an IANA zone name such as Europe/London. The exception is a future event meant for a local time, such as a meeting at 9:00 in New York: keep that local time and the zone name, because daylight saving rules can change.
Sources and further reading
- Date and Time on the Internet: Timestamps (RFC 3339) — Internet Engineering Task Force
- ISO 8601: Date and time format — International Organization for Standardization
- 4. General Concepts (POSIX base definitions, Seconds Since the Epoch) — The Open Group
- Date.now() — MDN Web Docs
- Date — MDN Web Docs
- Five different ways to handle leap seconds with NTP — Red Hat Developer
- 4.1. Index Nodes (ext4) — The Linux Kernel documentation
- ISO 8601-1:2019, Basic rules — International Organization for Standardization
- Date.prototype.getMonth() — MDN Web Docs
- Leap Smear — Google for Developers
- Approaching the kernel year-2038 end game — LWN.net
- PEP 495: Local Time Disambiguation — Python Software Foundation
- Storing times for human events — Simon Willison's Weblog