Open a database, a log file, or an API response and sooner or later you meet a bare number like 1700000000 sitting where a date should be. It looks cryptic, but it is one of the simplest ideas in computing: a running count of seconds since a single fixed instant. Learn what that instant is and how the count behaves, and a whole family of confusing date bugs turns into something you can reason about on paper. This is the editorial explainer. If you just want to paste a number in and read the date back, the epoch converter does the arithmetic for you.
The one-line definition
Unix epoch time, also called a Unix timestamp or POSIX time, is the number of seconds that have elapsed since 00:00:00 on 1 January 1970, measured in Coordinated Universal Time (UTC). That starting instant is the epoch. Everything after it is a positive count; the rare instant before it is a negative one. The value is a plain integer, which is exactly why it is so useful. You can store it in a single column, sort by it, subtract two of them to get a duration in seconds, and never once think about the calendar until you need to show the result to a person.
The number carries no year, month, day, hour, or time zone inside it. Those are all things you compute from it when you want a readable date. The timestamp itself is closer to a measurement than to a calendar entry: it says how far along a straight line of seconds you are, and nothing more.
Why 1970, of all years?
There is no astronomical or historical significance to 1 January 1970. The date is a leftover from the early days of Unix at Bell Labs in the early 1970s. The team needed a zero point for the system clock, picked the start of a convenient recent year that sat just before the system itself existed, and moved on. The choice was pragmatic, it got baked into the operating system, and from there it propagated into C, into every language that borrowed C's time handling, and eventually into databases, file systems, and network protocols across the industry.
The lesson worth keeping is that a good enough convention, adopted early and widely, becomes a de facto standard regardless of whether the original reasoning was profound. Nobody defends 1970 on its merits today; they use it because everything else already does.
Why it is stored in UTC, and why that makes it timezone-agnostic
The epoch is pinned to UTC, and this single decision is what makes a Unix timestamp so well behaved. Because the count is defined against one global clock, the same real-world instant produces the identical number whether it is generated in Tokyo, London, or Los Angeles. A server in one country and a phone in another that record an event at the same moment will write down the same timestamp, with no negotiation about offsets.
That is what people mean when they call the value timezone-agnostic. It is not that time zones are ignored; it is that they are simply not part of the stored value. A time zone only matters at the very end, when you turn the number into words a human can read. Take the same timestamp and render it for New York and it reads one wall-clock time; render it for Sydney and it reads another; but the underlying instant, and the underlying number, never changed. This is why the standard advice for storing a moment in time is to store the UTC instant and attach a zone only for display. The tradeoffs of that approach in a real schema are covered in how to store dates and times in a database.
The leap-second caveat
Here is the detail that trips up people who assume the count is a perfect tally of every physical second since 1970. It is not. Unix time deliberately ignores leap seconds. A leap second is an occasional one-second adjustment inserted into UTC to keep clock time aligned with the slightly irregular rotation of the Earth. Unix time pretends these insertions never happen: it treats every single day as exactly 86400 seconds long, no exceptions.
The upshot is that a Unix timestamp is not the true number of elapsed physical seconds since the epoch; it is the number of seconds under the fiction that no leap seconds ever occurred. The benefit of that fiction is enormous. Converting a timestamp to a calendar date is pure, predictable arithmetic, because you can always divide by 86400 to get whole days without worrying about which historical days were a second longer. For the overwhelming majority of software this simplification is exactly what you want, and the leap-second gap only becomes relevant in domains that demand sub-second alignment with astronomical time.
Seconds or milliseconds? The unit that ruins dates
The classic Unix timestamp counts seconds. But a great deal of software, JavaScript most prominently, counts milliseconds since the same 1970 epoch instead. JavaScript's Date.now() returns milliseconds, and so does the number you get from a Date object. Databases, spreadsheet exports, Unix command-line tools, and many backend languages lean toward seconds. The two look almost identical, differing only by a factor of a thousand, which is exactly what makes the mistake so easy and so destructive.
Get the unit wrong and you do not get a slightly off date, you get a wildly wrong one. Hand a millisecond value to something expecting seconds and the date rockets tens of thousands of years into the future. Do the reverse, treating seconds as milliseconds, and the date collapses back to within days of 1 January 1970. Neither failure is subtle once you notice it, but both sail through code review because the number still looks like a plausible timestamp. The habit that saves you is to always ask which unit a value is in before you convert it, and to label your variables accordingly. The same seconds-versus-milliseconds boundary shows up all over the browser platform, which is why it gets its own treatment in the JavaScript date and time guide.
A worked example, both directions
Take the timestamp 1700000000. To read it as a date by hand, divide by 86400 to count whole days since the epoch: that gives 19675 complete days plus a remainder. Nineteen thousand six hundred and seventy-five days after 1 January 1970 lands on 14 November 2023, and the leftover seconds work out to 22:13:20. So 1700000000 is 2023-11-14 22:13:20 UTC. If you rendered that for a viewer in a zone three hours behind UTC, they would see 19:13 on the same date; the number never moved, only the label did.
Going the other way, suppose you want the timestamp for the very start of that day, midnight UTC on 14 November 2023. You count the whole days from the epoch to that date, which is 19675, and multiply by 86400 seconds per day. The result is 1699920000. Notice that the two values differ by exactly 80000 seconds, which is 22 hours, 13 minutes, and 20 seconds, the time-of-day part we peeled off in the first direction. That symmetry, days times 86400 plus seconds-into-the-day, is the whole of the conversion, and it works precisely because Unix time treats every day as the same length.
Now watch the unit trap in the same example. If you accidentally passed 1700000000000, the millisecond form, into a routine that expected seconds, it would treat that as a seconds count and place the date somewhere around the year 55840. That is not a rounding error, it is a fifty-thousand-year miss, and it comes entirely from the missing factor of a thousand.
The year 2038 problem
For decades the timestamp was commonly stored in a signed 32-bit integer. A signed 32-bit integer can hold a maximum value of 2147483647. Counting that many seconds from the 1970 epoch brings you to exactly 03:14:07 UTC on 19 January 2038, a Tuesday. One second later there is no larger positive value to move to. The counter overflows and wraps around to the most negative number the type can hold, which is interpreted as a date back in December 1901. A clock that has been climbing steadily for sixty-eight years suddenly reads as if it fell off the front of the twentieth century.
This is the year 2038 problem, and it is the direct descendant of the year 2000 problem: a storage format that was generous when it was chosen quietly running out of room. Any system that computes future dates, an expiry sixty years out, a long amortisation schedule, a certificate valid for decades, can hit the ceiling well before 2038 itself, because it is reaching past the limit today.
The fix is straightforward and already widespread: store the timestamp in a 64-bit signed integer instead of a 32-bit one. A 64-bit count of seconds does not exhaust for hundreds of billions of years, comfortably longer than the age of the universe, so the overflow simply stops being a practical concern. Modern operating systems, languages, and databases have largely moved to 64-bit time already. The remaining risk sits in old embedded devices, legacy file formats, and code that still narrows a timestamp back down to 32 bits somewhere in its pipeline.
What to carry away
A Unix timestamp is a count of seconds from a fixed 1970 UTC instant, and almost everything confusing about it follows from three footnotes to that definition. It is anchored to UTC, so it holds no time zone and reads identically everywhere. It ignores leap seconds, so the conversion to a calendar date is clean division by 86400. And it comes in two units, seconds and milliseconds, whose thousandfold gap is the single most common way a date ends up catastrophically wrong. Keep those three in mind, remember that a 32-bit version runs out in January 2038, and the bare number in your logs stops being a mystery. When you need to check a specific value rather than reason about the mechanism, the epoch converter turns it into a readable date in both directions.
Frequently asked questions
What is Unix epoch time in one sentence?
It is a single integer that counts the number of seconds elapsed since 00:00:00 on 1 January 1970 in Coordinated Universal Time, so a value like 1700000000 is just a count of seconds from that fixed starting instant.
Why was 1 January 1970 chosen as the epoch?
The convention comes from early Unix at Bell Labs in the early 1970s. The developers needed a simple zero point for the system clock, and the start of the nearest whole year, 1970, was a convenient round choice that sat just before the system existed. It carries no cosmic meaning; it is an engineering decision that stuck and then spread to almost every language and operating system.
Does a Unix timestamp include a time zone?
No. The value is defined against UTC and stores no offset at all. The same instant produces the same number everywhere on Earth. A time zone only enters the picture when you convert the number into a human-readable local date, which is a display step layered on top, not part of the stored value.
Why is my date off by decades or thousands of years?
Almost always a seconds-versus-milliseconds mix-up. JavaScript and many other environments count milliseconds since the epoch, while Unix tools and most databases count seconds. Feed a millisecond value into a function expecting seconds and the date lands roughly fifty thousand years in the future; do the reverse and it collapses back toward 1970. Check the unit before you convert.
What is the year 2038 problem?
Systems that store the timestamp in a signed 32-bit integer can only reach 2147483647 seconds, which is 03:14:07 UTC on 19 January 2038. One second later the counter overflows and wraps to a large negative number, throwing the date back to 1901. The fix is to store the value in a 64-bit integer, which pushes the limit hundreds of billions of years into the future.