← All posts

Epoch Timestamp vs Unix Time vs POSIX Time

In most developer docs, epoch timestamp, Unix timestamp, Unix time, and POSIX time all mean seconds since 1970-01-01 00:00:00 UTC. The differences matter when the unit is milliseconds, the epoch is not 1970, the value is before 1970, or leap seconds and standards language are involved.

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:

  1. What epoch does it count from?
  2. What unit does it use?
  3. Is the value signed?
  4. 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.