The short answer
For most web and backend work, these terms point to the same value:
Unix timestamp = Unix time = POSIX time = seconds since 1970-01-01 00:00:00 UTC
But the terms are not perfectly interchangeable. The differences show up when a value crosses a system boundary.
| Term | Usually means | Use it when | Watch for |
|---|---|---|---|
| Unix timestamp | seconds since 1970-01-01 00:00:00 UTC |
API docs, logs, CLI examples, database filters | some APIs use milliseconds while still saying timestamp |
| Unix time | same 1970-based seconds count | explaining the concept or OS/runtime behavior | readers may ask whether it includes leap seconds |
| POSIX time | the standards-defined "seconds since the Epoch" value | standards, compliance, C/POSIX docs, leap-second discussions | POSIX fixes each represented day at 86400 seconds |
time_t |
the C/POSIX storage type used by time() |
C, libc, embedded systems, OS APIs | width, signedness, and 2038 behavior depend on the implementation |
| Epoch timestamp | a count from an epoch, often Unix | broad user help and converter pages | epoch and unit may not be 1970 seconds |
If you are naming something in code, do not rely on the reader guessing the term. Use the unit: createdAtUnixSeconds, expiresAtEpochMs, event_time_s, or recorded_at_ms.
A practical rule for reading any timestamp field
When I see a field named only timestamp, I do not start with the definition. I start with the value.
| Value shape | Most likely meaning | Quick check |
|---|---|---|
1700000000 |
Unix seconds | 10 digits in the 2020s |
1700000000000 |
Unix milliseconds | 13 digits; common in JavaScript and Java |
1700000000000000 |
Unix microseconds | 16 digits; common in databases and tracing |
1700000000000000000 |
Unix nanoseconds | 19 digits; common in Go, Linux, telemetry |
133444736000000000 |
Windows FILETIME-like value | large 100 ns count from 1601 |
3913056000 |
NTP seconds-like value | 1900-based seconds, not Unix seconds |
Then ask four questions:
- What epoch does it count from?
- What unit does it use?
- Is the value signed?
- Is it an instant, a local date, or a duration?
Most timestamp bugs come from answering one of those four questions wrong.
What "epoch timestamp" really means
An epoch is a starting point. An epoch timestamp is a numeric count from that starting point.
In everyday developer searches, "epoch timestamp" usually means the Unix epoch:
- Epoch:
1970-01-01 00:00:00 UTC - Unit: seconds, unless the source says milliseconds or another unit
- Example:
1700000000=2023-11-14 22:13:20 UTC
The phrase is broader than Unix, though. Windows FILETIME, NTP, GPS time, Excel serial dates, and .NET ticks are all epoch-based systems. They just choose a different start date, different unit, or different treatment of leap seconds.
That is why a converter should ask "which format?" before converting a number. 1700000000 is a normal Unix seconds value. A Windows FILETIME value with 17 or 18 digits needs FILETIME conversion, not Unix conversion.
Unix time vs POSIX time
Unix time is the developer-friendly name. POSIX time is the standards-friendly name.
Both refer to seconds since the Epoch, where the Epoch is 1970-01-01 00:00:00 UTC. The Open Group POSIX text defines "Seconds Since the Epoch" with a calendar formula and states that each represented day is accounted for by exactly 86400 seconds.
That detail is the reason POSIX time is useful in specs. It tells implementers how to map a UTC calendar label to a single integer without storing a timezone or leap-second table inside every timestamp.
Use the terms like this:
- Say "Unix timestamp" in API docs and product docs.
- Say "POSIX time" when you need the standard's exact behavior.
- Say "seconds since the Epoch" when you are writing C/POSIX-oriented technical docs.
- Say "epoch timestamp" when the user may be searching broadly and you will define the unit immediately.
Where leap seconds make the terminology matter
Unix and POSIX timestamps are excellent for ordering logs, storing expiry times, indexing database rows, and moving instants through APIs. They are not a perfect count of physical SI seconds since 1970.
Why? UTC occasionally has leap seconds. POSIX-style time still represents every day as exactly 86400 seconds. During a positive leap second, the civil clock may show 23:59:60, but the simple Unix/POSIX integer does not get a clean extra value for that display label.
In real systems, the time service decides what to do:
- Step the clock.
- Repeat or skip a displayed second.
- Smear the leap second across a window.
- Keep an internal atomic/GPS/TAI-aligned timescale and convert for display.
As of IERS Bulletin C 72, published July 6, 2026, no leap second will be introduced at the end of December 2026, and UTC-TAI remains -37 s. That means TAI is 37 seconds ahead of UTC. GPS time is different again because it started with a 19-second offset from TAI, so GPS is currently 18 seconds ahead of UTC.
For normal web applications, this is mostly background knowledge. For high-frequency trading, satellites, telecom, distributed tracing, metrology, or systems that must measure elapsed physical time across a leap-second boundary, it is not background at all. Use a monotonic clock for durations and a domain-appropriate time scale for precision timing.
The time_t detail engineers still trip over
time_t is not a synonym you should use in user-facing docs. It is the C type behind many Unix-like time APIs.
In common POSIX usage, time() returns a time_t value representing seconds since the Epoch. The problem is that old systems and embedded systems may still store it in 32 bits. A signed 32-bit seconds value reaches its maximum at:
| Value | UTC date | Meaning |
|---|---|---|
2147483647 |
2038-01-19 03:14:07 |
largest signed 32-bit Unix seconds value |
-2147483648 |
1901-12-13 20:45:52 |
lowest signed 32-bit Unix seconds value |
4294967295 |
2106-02-07 06:28:15 |
largest unsigned 32-bit seconds value, but no negative dates |
This is the Year 2038 problem. The timestamp concept is fine; the old storage width is the bug.
Other epoch timestamps that are not Unix time
The moment a value does not decode to a sensible date, check whether it uses a different epoch.
| System | Epoch | Unit | Unix conversion clue |
|---|---|---|---|
| Unix / POSIX | 1970-01-01 00:00:00 UTC |
seconds | no offset needed |
| Unix milliseconds | 1970-01-01 00:00:00 UTC |
milliseconds | divide by 1000 for Unix seconds |
| Windows FILETIME | 1601-01-01 00:00:00 UTC |
100 ns intervals | divide by 10000000, then subtract 11644473600 |
| NTP timestamp | 1900-01-01 00:00:00 UTC |
seconds + fractional seconds | subtract 2208988800 from the seconds part |
| GPS time | 1980-01-06 00:00:00 |
seconds, no UTC leap seconds | apply the GPS-UTC offset for the date |
| .NET ticks | 0001-01-01 00:00:00 |
100 ns intervals | subtract 621355968000000000, then divide by 10000000 |
| Apple Core Data | 2001-01-01 00:00:00 UTC |
seconds | add 978307200 |
Microsoft documents FILETIME as 100-nanosecond intervals since January 1, 1601 UTC. RFC 5905 defines NTP's prime epoch as 0h on January 1, 1900 UTC. Both are epoch timestamp systems. Neither is Unix time until you apply the offset.
Naming examples for APIs, databases, and logs
Good timestamp naming prevents future production bugs. The name should say the meaning and the unit.
| Bad name | Better name | Why |
|---|---|---|
timestamp |
createdAtUnixSeconds |
says it is Unix seconds |
createdAt |
createdAtEpochMs |
says it is numeric milliseconds, not ISO text |
time |
event_time_s |
clear for logs and warehouses |
expires |
expires_at_unix_s |
explicit expiry instant and unit |
date |
local_date |
date-only values are not instants |
durationTimestamp |
duration_ms |
durations are not timestamps |
Use native datetime types when the database needs timezone-aware querying and formatting. Use integer epoch fields when you need compact event streams, cache keys, queues, expiry checks, or protocol compatibility. If you use integers, include the unit in the name.
Common search phrases and what they usually mean
People use these phrases loosely, so it helps to know what each one usually points to and what to check next.
| Search phrase | Usually means | What to check next |
|---|---|---|
| epoch timestamp | Unix timestamp, often seconds | confirm the epoch and the unit |
| Unix timestamp | seconds since 1970 UTC | 10-digit values in the 2020s |
| Unix time | same as Unix timestamp | it is a timezone-neutral instant |
| POSIX time | standards-defined Unix time | 86400-second days, no leap seconds |
| timestamp Unix time | convert a date or value to Unix seconds | which direction you need to convert |
| epoch milliseconds | milliseconds since 1970 UTC | 13-digit values; divide by 1000 for seconds |
| time_t | C/POSIX storage type | 32-bit vs 64-bit range |
If you just want to convert a value, use a converter tool. If you want to understand what the words mean, this page is the terminology bridge for the rest of the timestamp guides.
Worked examples
These values are useful anchors:
| Value | If interpreted as | UTC result |
|---|---|---|
0 |
Unix seconds | 1970-01-01 00:00:00 |
1 |
Unix seconds | 1970-01-01 00:00:01 |
86400 |
Unix seconds | 1970-01-02 00:00:00 |
1700000000 |
Unix seconds | 2023-11-14 22:13:20 |
1700000000000 |
Unix milliseconds | 2023-11-14 22:13:20 |
1767225600 |
Unix seconds | 2026-01-01 00:00:00 |
2147483647 |
Unix seconds | 2038-01-19 03:14:07 |
The fastest sanity test is this: if a value that should be recent becomes January 1970, seconds were probably treated as milliseconds. If it becomes a distant future date, milliseconds were probably treated as seconds.
Related articles
FAQ
- Is epoch timestamp the same as Unix time?
- Usually, yes. In web APIs, logs, Linux commands, and database examples, epoch timestamp usually means Unix time: seconds since 1970-01-01 00:00:00 UTC. Still confirm the unit, because many JavaScript and Java values are epoch milliseconds.
- What is the difference between Unix time and POSIX time?
- For normal application work, they are the same number. Unix time is the common historical name; POSIX time is the standards-defined version of seconds since the Epoch, with each represented day treated as exactly 86400 seconds.
- What does POSIX time mean?
- POSIX time means seconds since the POSIX Epoch, 1970-01-01 00:00:00 UTC. The POSIX formula is designed for simple computation and does not create a separate timestamp for UTC leap seconds.
- Is time_t the same as a Unix timestamp?
- time_t is the C/POSIX type commonly used to hold Unix time. A value returned by time() is usually Unix seconds, but the exact width and signedness are implementation details, so old 32-bit code can still have range problems.
- Does Unix time count leap seconds?
- No. POSIX-style Unix time represents every day as 86400 seconds. Leap seconds are handled by the operating system or time service through stepping, repeating, smearing, or another implementation-specific method.
- Can Unix or POSIX timestamps be negative?
- Many modern systems support negative Unix timestamps for dates before 1970, such as -1 for 1969-12-31 23:59:59 UTC. POSIX's formal calendar-to-seconds relationship does not require portable behavior for negative values, so verify old libraries and databases.
- Is epoch time always in seconds?
- No. Classic Unix/POSIX time is seconds, but epoch timestamp is a broader phrase. It may mean seconds, milliseconds, microseconds, nanoseconds, Windows FILETIME ticks, NTP seconds, or another epoch-based count.
- Why do some APIs say epoch milliseconds?
- They use the same Unix epoch but count milliseconds instead of seconds. Date.now() in JavaScript returns a 13-digit millisecond value, while date +%s in Unix shells returns a 10-digit seconds value.
- Is Windows FILETIME an epoch timestamp?
- Yes, but it is not Unix time. Windows FILETIME counts 100-nanosecond intervals since 1601-01-01 UTC, so it needs an epoch offset before it becomes Unix seconds.
- Which term should I use in an API field name?
- Use a name that includes the unit, such as createdAtUnixSeconds, expiresAtEpochMs, or event_time_s. Avoid vague names like timestamp when the value crosses system boundaries.