Somewhere in almost every system you use, the current moment is stored not as a date but as a single large integer. Unix epoch time is that integer: a plain count of seconds elapsed since midnight at the start of 1 January 1970, Coordinated Universal Time. Nothing in the number names a month, a weekday or a country, which is precisely why it has outlived the operating system that gave it its name and turned up in file systems, cookies, JSON payloads and hardware clocks.

This article explains where the 1970 origin came from, how to tell a seconds value from a milliseconds value at a glance, what a negative timestamp means, and why the format needs no zone information. You can convert in either direction as you go with the Unix timestamp converter.

What Is Unix Epoch Time?

Unix epoch time is the number of seconds that have passed since 00:00:00 UTC on 1 January 1970, ignoring leap seconds. That instant is called the epoch, and every later moment is a positive count from it while every earlier moment is a negative one.

The formal name for the scheme is POSIX time, defined by the POSIX standard that most operating systems follow. POSIX deliberately treats every day as exactly 86,400 seconds long, which keeps the arithmetic simple at the cost of a small divergence from astronomical reality. In C the value has traditionally been held in a type called time_t, and that type's width is the source of a well-known deadline discussed below.

Why Does the Count Start in 1970?

The origin was a practical choice rather than a principled one. Early Unix developers needed a recent, round starting point that their hardware could count from without overflowing within the machine's expected lifetime, and the beginning of 1970 was simply the nearest convenient boundary when the work was done.

An earlier version of the clock ticked sixty times a second and rolled over in a little over two years, which was clearly impractical, so the team switched to whole seconds and moved the origin to the start of the decade. Nothing about 1970 is astronomically or historically significant. What matters is only that everybody agrees on it, and they do: the same origin is used by Java, JavaScript, Python, Go, Rust, MySQL, Postgres and effectively every network protocol that carries a timestamp.

Seconds or Milliseconds?

Count the digits. A ten-digit epoch value is in seconds, and a thirteen-digit value is in milliseconds. Mistaking one for the other throws a date off by roughly a factor of a thousand, which typically lands you either in 1970 or tens of thousands of years in the future.

The split is largely a matter of lineage. C and the Unix system calls count whole seconds. JavaScript counts milliseconds, so Date.now() returns a thirteen-digit number and the JavaScript Date constructor expects the same. Java followed the same convention, and so did most of the languages that borrowed from it. Some systems go further: Go and many databases store nanoseconds, and Python returns a float with microsecond resolution.

  • Ten digits: seconds. This form stays ten digits long until November 2286.
  • Thirteen digits: milliseconds, the JavaScript and Java convention.
  • Sixteen digits: microseconds, common in tracing and database internals.
  • Nineteen digits: nanoseconds, which overflow a signed 64-bit integer in 2262.

The safest habit is to name the unit in your field names, so that epochSeconds and epochMillis can never be silently swapped by a future reader. A second defensive trick is a sanity check on parse: if a value converts to a date outside a plausible window, say before 1990 or after 2100, the unit is almost certainly wrong rather than the data.

What Do Negative Timestamps Mean?

A negative Unix timestamp is a moment before the epoch. The value -1 is 23:59:59 UTC on 31 December 1969, and -86400 is exactly one day before the origin, at midnight starting 31 December 1969.

Negative values are perfectly legal and correctly handled by most modern libraries, but they are a well-known source of bugs in older code that assumed the count could never fall below zero. Historical dates expose the weakness quickly: a birth date in 1943 or an archive record from 1908 both produce negative numbers. Anything genuinely historical also raises a separate problem, because civil calendars and time zone offsets before the early twentieth century were irregular, and the further back you go the less precise the mapping becomes. Before standard time was adopted, many towns kept their own local mean solar time, so an eighteenth-century date converted with modern rules is an approximation dressed up as a precise integer. For genealogy, archives and anything else where the calendar date is the fact and the exact second is not, a plain date string is the better store.

Why Is Unix Epoch Time Free of Time Zones?

Because the count is defined against UTC and nothing else, a given epoch value identifies one instant everywhere on Earth. Two servers in Tokyo and Lisbon recording the same event record the same number; only the rendering into a human-readable date differs.

That property is the whole point. A wall-clock string such as "2026-03-29 01:30" may be ambiguous, may not exist at all, or may occur twice, depending on that region's daylight saving rules. An integer cannot suffer any of those problems. It is why epoch values are the natural storage form for anything that happened, and why the advice in why you should store dates in UTC so often ends in the same place. The conversion back to a human-facing string belongs at the edge of your system, using a zone identifier that you keep separately.

What Epoch Time Cannot Represent

Two things sit outside the model, and both surprise people. Neither is a defect exactly; they are consequences of the simplifying choices that make the format useful.

  • Leap seconds: POSIX time pretends every day has 86,400 seconds, so an inserted leap second is not counted. In practice systems repeat or smear a second instead. The mechanics are covered in leap seconds explained.
  • Future local events: a timestamp cannot express "09:00 next March in Berlin", because a government may move the offset before then. Store the local time and the zone name instead.
  • Dates beyond the integer width: a signed 32-bit counter runs out in January 2038, the subject of the year 2038 problem.
  • Precision beyond the stored unit: a seconds-resolution value cannot order two events in the same second, which matters more than you would expect in log correlation.

None of these rules out epoch storage. They simply mark the places where a second field is needed alongside the number.

Conclusion

Unix epoch time is one integer with one meaning: seconds since the start of 1970 in UTC, with no zone, no calendar and no ambiguity. Remember that ten digits are seconds and thirteen are milliseconds, that negative values are ordinary dates before 1970, and that the number should be converted to local form only when a human is about to read it. For the readable equivalent, format the same instant with the ISO 8601 formatter, translate any raw value with the Unix timestamp converter, or see the current moment in every notation at once on localdatetime.now.