Home / Guides / What is Unix time?

What Is Unix Time?

A clear guide to Unix time: the epoch, seconds against milliseconds, negative values, leap seconds, the Year 2038 problem, how it compares with ISO 8601, and how to store time without bugs.

Unix time in one paragraph

Unix time (POSIX time, epoch time) counts the seconds since 00:00:00 UTC on Thursday, 1 January 1970. That starting point is called the Unix epoch. A moment is stored as a single integer, so it is easy to store, sort, compare and subtract, and it does not depend on a time zone, a calendar or a language.

Why 1970?

Early versions of Unix at Bell Labs needed a fixed starting date for their clocks. The date was moved around in the first years, and the start of 1970 was settled on as a round and recent point. There is no deeper meaning. Because the standard (POSIX) and the C library used it, nearly every programming language and operating system adopted the same epoch.

Seconds, milliseconds and finer units

UnitDigits todayExample for 2023-11-14 22:13:20 UTC
Seconds101700000000
Milliseconds131700000000000
Microseconds161700000000000000
Nanoseconds191700000000000000000

The classic Unix timestamp is in seconds. JavaScript and Java use milliseconds. When a value looks like a date in 1970 or in the far future, the unit is almost always the cause. The milliseconds to date converter handles the 13-digit case.

Dates before 1970

Negative numbers count backwards from the epoch. -1 is 23:59:59 UTC on 31 December 1969 and -86400 is 00:00:00 on that day. A signed integer is needed to store them. Some systems, such as those that store the value as unsigned, cannot represent dates before 1970.

Unix time and leap seconds

UTC sometimes adds a leap second so that clocks stay in step with the rotation of the Earth. Unix time does not count them: it assumes that every day has exactly 86,400 seconds. When a leap second happens, Unix time either repeats a second or is smeared over a longer period, depending on the system. The effect is that Unix time is not a perfect count of elapsed SI seconds. For measuring a duration to the second across a leap second, use a monotonic clock. For storing when something happened, Unix time is fine.

The Year 2038 problem

Many older systems store Unix time in a signed 32-bit integer. The largest value it can hold is 2147483647, which is 03:14:07 UTC on 19 January 2038. One second later the value overflows and becomes negative, and a date in 1901 appears. Embedded devices, old file formats and some database columns are at risk.

  • A 64-bit integer holds about 292 billion years in each direction, so it ends the problem. Most modern operating systems and languages have moved to it.
  • An unsigned 32-bit integer reaches 4294967295, which is 6 February 2106, but it cannot store dates before 1970.
  • In databases, check the column type. The MySQL TIMESTAMP type is limited to 2038-01-19 03:14:07 UTC. Use DATETIME or a 64-bit integer for later dates.

Unix time, UTC and ISO 8601

Unix timeISO 8601
FormAn integerText, such as 2023-11-14T22:13:20Z
Readable by peopleNoYes
Time zoneAlways UTC, never storedStored as Z or an offset
Sorting and mathsTrivialSorts as text when the zone is the same
Best forStorage, tokens, logs, calculationsAPIs and files that people read

Good practice for storing time

  1. Store UTC. Keep the instant as a Unix timestamp or as UTC text, and convert to a time zone only when you show it.
  2. Keep the unit explicit. Put it in the field name (created_at_ms) or in the API documentation.
  3. Use 64-bit integers.
  4. Store the time zone separately when the local wall time matters, for example a meeting at 09:00 in Paris. A fixed offset is not enough, because the offset changes with daylight saving time. Keep the zone name, such as Europe/Paris.
  5. Do not add 86400 to mean "tomorrow" for local calendar days. Use your language's date library in that time zone.
  6. Sync clocks with NTP, and allow a small tolerance when you compare timestamps from different machines.

Common bugs

  • Seconds treated as milliseconds, or the opposite.
  • Parsing a date string without a zone, so each machine reads it as its own local time.
  • Showing the UTC value to a user without converting it to their time zone.
  • Comparing a timestamp in seconds with one in milliseconds.
  • Floating-point rounding: a double holds integers exactly up to 253, which is fine for milliseconds but not for nanoseconds. Use 64-bit integers or strings for those.

Other epochs

Windows FILETIME starts in 1601, .NET ticks in year 1, Apple Cocoa time in 2001 and Excel serial dates in 1899. See the epoch converter for a table and for a converter that shows all of them.

All timestamp tools on this site

Frequently asked questions

What is Unix time?

The number of seconds since 00:00:00 UTC on 1 January 1970, not counting leap seconds.

Why does Unix time start in 1970?

It was the starting point chosen by early Unix developers. It became the standard because POSIX and the C library adopted it.

What is the Year 2038 problem?

A signed 32-bit Unix timestamp overflows on 19 January 2038 at 03:14:07 UTC. Using 64-bit integers avoids it.

Does Unix time include leap seconds?

No. It treats every day as 86,400 seconds, so a leap second repeats or is smeared.

Should I store dates as Unix timestamps or ISO 8601 strings?

Both are fine if they are UTC. Timestamps suit storage and maths, and ISO 8601 suits files and APIs that people read.