What is a Unix timestamp, and why do so many systems use it?
What a Unix timestamp actually counts, how to tell seconds from milliseconds, where UTC and ISO 8601 come in, what the year 2038 problem is and which mistakes appear when systems are connected.
By Javier Tenjo, Full stack developer
On this page
You export your shop’s orders or look at an API response and, where you expected a date, you find a number like 1700000000. It is not an error or an internal code: it is a date, written the way computers prefer.
That number is called a Unix timestamp, and it sits behind almost every system a business works with: databases, payment gateways, CRMs, server logs. Understanding how it works saves you from many of the silliest and most expensive integration mistakes, the ones that make an order appear dated 1970 or shift an appointment by five hours.
The Unix epoch: counting seconds from a fixed point
A Unix timestamp is the number of seconds elapsed since midnight UTC on 1 January 1970. That instant zero is called the “Unix epoch”. The creators of the Unix operating system picked it as a round, recent starting point, and it stuck.
1700000000 is one billion seven hundred million seconds after that instant, which in readable form is 2023-11-14T22:13:20Z. Every second that passes, the number goes up by one.
Why use a number rather than a written date? Three practical reasons:
- It does not depend on language or format. Nobody has to decide whether the day or the month comes first, or what the months are called.
- It carries no time zone. The same number is the same instant in Bogotá, London and Tokyo. The zone only appears when you display it.
- It is easy to calculate with. Working out how long passed between two moments is a subtraction. Adding a day means adding 86,400.
One technical detail: Unix time ignores leap seconds. As far as it is concerned, every day lasts exactly 86,400 seconds. For a business it has no practical effect, but it explains why two very precise clocks can disagree by a second.
Seconds, milliseconds and beyond
Not every system counts in seconds. Many use smaller units, and the quick way to tell which is to count the digits:
| Digits (current dates) | Unit | Where it shows up |
|---|---|---|
| 10 | Seconds | The classic standard: PHP, many databases and APIs |
| 13 | Milliseconds | JavaScript, Java, many web APIs |
| 16 | Microseconds | Some databases and logs |
| 19 | Nanoseconds | Go, high-precision measurement systems |
Getting the unit wrong does not raise an error: it produces an absurd date. Read milliseconds as seconds and the result lands tens of thousands of years in the future. Read seconds as milliseconds and the date is stuck in the first days of January 1970. When you see an order dated 1970 in a report, this is almost always why.
UTC, time zones and offsets
UTC (Coordinated Universal Time) is the reference every time zone is measured against. Colombia sits at UTC−5 all year round. The United Kingdom is at UTC+0 in winter and UTC+1 in summer.
That last sentence holds the distinction that prevents the most confusion: an offset is not a time zone. -05:00 is an offset: a number of hours from UTC. America/Bogota is a zone: a place, with its own history of clock changes. If you store only the offset, you know what time it was at that moment, but you cannot correctly work out what time it will be there in six months, because you do not know whether that place changes its clocks.
The rules for each zone live in the IANA time zone database, maintained by volunteers and updated several times a year because governments change their clocks. Operating systems and browsers ship with it built in.
The practical rule for any system: store instants in UTC (or as a timestamp) and convert them to the user’s zone only when displaying them.
ISO 8601: the readable way to say the same thing
When a date also has to be read by a person, or travel in a CSV file or an API, the format to use is ISO 8601:
2025-03-15T14:30:00Z or 2025-03-15T09:30:00-05:00
Year, month and day, the letter T, the time, and the zone at the end: Z for UTC or an explicit offset. Both lines in the example are the same instant. It has two advantages over any other written format: it is unambiguous (nobody wonders whether 03 is the day or the month) and it sorts alphabetically in the same order as chronologically, which makes it handy in file names and spreadsheets.
The year 2038 problem
For decades, many systems stored the timestamp as a signed 32-bit integer. The largest number that fits is 2147483647, which corresponds to 03:14:07 UTC on 19 January 2038. One second later the counter overflows, turns negative and the date jumps back to 1901.
It is a cousin of the famous millennium bug, with one difference: here the limit is not how the year is written but the size of the number. Modern 64-bit systems do not have the problem (their limit is billions of years away). But embedded devices, industrial equipment, old databases and file formats with 32-bit fields are still around. MySQL’s TIMESTAMP type, for example, does not accept dates after 2038.
And there is no need to wait until 2038 to run into it: any system that calculates future dates, such as the end of a fifteen-year loan, a long warranty or a multi-year subscription, may already be hitting that limit.
The mistakes that appear when systems are connected
- Mixing units. One system sends milliseconds and the other expects seconds. The result: dates in 1970 or in the year fifty thousand.
- Dates without a zone. A field such as
2025-03-15 09:30:00, with noZand no offset, is interpreted in the zone of whichever server reads it. Migrate to a server configured for another zone and every time shifts. - Dates without a time that change day. A bare date is often interpreted as midnight UTC, and in any zone west of Greenwich that midnight is still the previous day. That is why a birthday or a delivery date shows up a day early.
- Day and month swapped.
03/04is 3 April in one system and 4 March in another. In a CSV import it goes through without any warning until the 13th of the month arrives. - Daylight saving. “Every 24 hours” and “every day at 9:00 local time” are not the same in a zone that changes its clocks. The same applies to scheduled jobs: the server’s zone decides when they run, as we explain in cron expressions explained.
- Clocks out of sync. If servers do not synchronise their time with a time service, their timestamps disagree, and the logs of two systems cannot be compared.
Converting yours
The Unix timestamp converter accepts whatever you have to hand: a ten or thirteen digit timestamp, an ISO 8601 date or one written with slashes. It detects whether the number is in seconds, milliseconds, microseconds or nanoseconds and tells you what it assumed. You choose the zone to interpret it in and it gives you the same date in ISO 8601, in UTC, in RFC 2822, in SQL format and written out in words, along with the day of the week, the ISO week and how long ago it was. You can see the same instant across several time zones at once, and it warns you when a date with slashes could be read the other way round by another system.
When an integration shows a date that does not add up, pasting the original value in there is usually enough to see whether the problem is the unit, the zone or the format.
A Unix timestamp is just a counter of seconds, and that is exactly why it is so reliable: it has no language, no format and no zone. The problems appear when it is turned into something readable. Store in UTC, exchange in ISO 8601 and always check the unit, and most cases are covered.