What a Unix timestamp actually is
A Unix timestamp is a single integer: the number of seconds that have elapsed since 1970-01-01T00:00:00Z, called the Epoch. Nothing else is encoded in it. There is no time zone, no calendar, no daylight saving rule and no ambiguity, which is exactly why it is the representation almost every database, log format and API uses internally.
The reason it works so well is that comparison and subtraction become plain arithmetic. Deciding whether one event preceded another is an integer comparison. The gap between two events is one subtraction. Neither operation has to know that February has a variable length or that a country moved its clocks. Every complication in civil timekeeping lives in the conversion at the edges, and this calculator is that conversion.
POSIX defines the value formally as “seconds since the Epoch” computed from a UTC calendar date by an expression that treats every day as exactly 86,400 seconds. That definition has a consequence people find surprising: because UTC has occasionally inserted a leap second, a Unix timestamp is not a true count of elapsed SI seconds since 1970. It is a count of the days-and-seconds you would read off a UTC calendar. As of the last insertion in December 2016, the accumulated difference is 27 seconds. The trade-off is deliberate — the mapping between timestamps and calendar dates stays exact and reversible, which matters more for almost every application than 27 seconds do.
Some systems store finer units. JavaScript, Java and most JSON APIs use milliseconds; Python's time.time_ns, PostgreSQL and many tracing systems use microseconds or nanoseconds. The count is the same, scaled, and the unit selector here divides it back down before anything else happens.
The formula, one variable at a time
Going from a date to a timestamp is t = 86400N + 3600h + 60m + s − 3600Z, where N is the count of whole days from 1970-01-01 to your date. The offset term Z is subtracted because a local clock reading is ahead of UTC by its offset; a 09:00 reading at UTC+5:30 is 03:30 UTC, five and a half hours earlier.
Computing N is the only non-obvious part, because it has to respect the Gregorian leap rule — leap years are those divisible by 4, except centuries not divisible by 400. This calculator uses a closed-form days-from-civil algorithm that shifts the year to start in March, so the leap day falls at the end of the cycle and no special case is needed. It is exact for any year, including before the epoch, where N is negative. The leap year calculator explains the rule itself in detail.
The inverse is two floor operations. days = ⌊t/86400⌋, and seconds-of-day is the remainder t − 86400 × days. Using a true floor rather than truncation matters: for negative timestamps, truncating toward zero puts the seconds-of-day negative and shifts the date by a day. That is a real and common off-by-one bug in hand-rolled date code.
Day of week falls out for free. 1970-01-01 was a Thursday, so the index is ((days mod 7) + 4) mod 7 with 0 meaning Sunday. Because the epoch anchors it, no separate calendar rule is needed — which is one reason the day of week calculator and this one always agree.
Worked example: decoding the timestamp 1,000,000,000
The billionth second of the epoch was noted at the time by Unix users; here is how you get its date from the integer alone.
- Whole days. ⌊1,000,000,000 / 86,400⌋ = ⌊11,574.074⌋ = 11,574 days.
- Seconds accounted for by those days. 11,574 × 86,400 = 999,993,600 s.
- Seconds within the final day. 1,000,000,000 − 999,993,600 = 6,400 s.
- Hour. ⌊6,400 / 3,600⌋ = 1, using 3,600 s.
- Minute. ⌊(6,400 − 3,600) / 60⌋ = ⌊2,800 / 60⌋ = 46, using 2,760 s.
- Second. 2,800 − 2,760 = 40. So the time of day is 01:46:40 UTC.
- Date. Converting 11,574 days after 1970-01-01 through the Gregorian rule gives 2001-09-09.
- Day of week. 11,574 mod 7 = 3, so (3 + 4) mod 7 = 0, which is Sunday.
The full ISO 8601 form is 2001-09-09T01:46:40Z. Reverse the calculation to check: 11,574 × 86,400 + 1 × 3,600 + 46 × 60 + 40 = 999,993,600 + 3,600 + 2,760 + 40 = 1,000,000,000. In milliseconds the same instant is 1,000,000,000,000 — three more digits, same moment.
Landmark epoch values
| Timestamp (s) | UTC date and time | Day | Days since epoch |
|---|---|---|---|
| −2,147,483,648 | 1901-12-13 20:45:52 | Friday | −24,856 |
| −1 | 1969-12-31 23:59:59 | Wednesday | −1 |
| 0 | 1970-01-01 00:00:00 | Thursday | 0 |
| 946,684,800 | 2000-01-01 00:00:00 | Saturday | 10,957 |
| 1,000,000,000 | 2001-09-09 01:46:40 | Sunday | 11,574 |
| 1,234,567,890 | 2009-02-13 23:31:30 | Friday | 14,288 |
| 1,500,000,000 | 2017-07-14 02:40:00 | Friday | 17,361 |
| 1,704,067,200 | 2024-01-01 00:00:00 | Monday | 19,723 |
| 2,000,000,000 | 2033-05-18 03:33:20 | Wednesday | 23,148 |
| 2,147,483,647 | 2038-01-19 03:14:07 | Tuesday | 24,855 |
Each row is ⌊t/86400⌋ days plus the remainder as seconds of day, converted through the Gregorian calendar. The first and last rows are the signed 32-bit limits.
How to read the result
Start with the digit count, because it identifies the unit faster than anything else. For dates in the 2020s and 2030s a seconds timestamp has ten digits, milliseconds thirteen and microseconds sixteen. A ten-digit value read as milliseconds lands in January 1970, and a thirteen-digit value read as seconds lands tens of thousands of years in the future — both are unmistakable once you know to look, and the calculator warns when the magnitude and the selected unit disagree.
The UTC line is the authoritative one. The local line is only as good as the offset you typed, and it applies a fixed offset rather than a zone rule, so it will be an hour out if the date falls on the other side of a daylight saving transition from the offset you gave. Convert with the time zone converter when the zone rule matters.
A negative timestamp is legitimate and denotes an instant before 1970. Support for negative values is uneven in practice — some database drivers and embedded libraries clamp them at zero — so if you are storing historical dates, test the round trip rather than assuming it works. Astronomical and historical work is usually better served by a Julian date, which has no such discontinuity.
Values above 2,147,483,647 are past the range of signed 32-bit time_t. Sixty-four-bit systems are unaffected, but embedded devices, old file formats and some network protocols still carry 32-bit fields, and they wrap to December 1901 rather than failing loudly. If you are testing date handling, 2038-01-19T03:14:07Z and the second after it are the two values to try.
Mistakes that produce a wrong date
- Reading milliseconds as seconds. The single most common epoch bug. A JavaScript
Date.now()value divided by nothing lands your date around the year 56,000. - Truncating instead of flooring for negative timestamps. Truncation toward zero produces a negative seconds-of-day and shifts pre-1970 dates by one day.
- Assuming the timestamp carries a time zone. It does not. Any local time you display is a rendering decision made downstream, not a property of the value.
- Treating the difference of two timestamps as elapsed SI seconds. Across a leap second insertion it is short by one second, because POSIX time skips them.
- Applying a fixed offset across a daylight saving boundary. The offset you enter is used verbatim; the real zone may have used a different one on that date.
- Storing a timestamp in a 32-bit column. It works until 2038-01-19 and then silently wraps to 1901 rather than raising an error.
POSIX.1-2017 and the definition of “seconds since the Epoch”
The POSIX standard (IEEE Std 1003.1-2017) defines the relationship between a timestamp and a UTC calendar date by an explicit expression that counts 86,400 seconds per day, 31,536,000 seconds per non-leap year, plus a day for each leap year in between. It states directly that the value does not necessarily equal the number of seconds actually elapsed, because leap seconds are excluded. ISO 8601 governs the textual form — 2001-09-09T01:46:40Z, where the trailing Z means UTC — and RFC 3339 profiles it for internet protocols, which is the form most APIs emit.
Related representations and when each is right
Use epoch seconds for anything a machine will compare or subtract. Use ISO 8601 for anything a human or another system will read, because it is unambiguous, sorts lexicographically in the same order as chronologically, and carries the offset explicitly. Keep the two in step by treating the timestamp as the stored value and the string as a rendering.
For calendar-level questions the arithmetic is easier elsewhere: the day of year calculator gives the ordinal date, the ISO week number calculator gives the week, and the age in days calculator counts days between two dates without going through seconds at all. Astronomers use the Julian date, a continuous day count from 4713 BC with no epoch discontinuity, which is why observation logs and ephemerides use it rather than epoch seconds.
If you need elapsed physical time rather than calendar time — for interval measurement, benchmarking or spacecraft navigation — use a monotonic clock or International Atomic Time (TAI) instead. TAI counts real SI seconds without interruption and currently runs 37 seconds ahead of UTC. A Unix timestamp difference is close enough for almost everything, and wrong by one second per intervening leap second when it is not.
