Skip to content
SimpleTools24

How to Get the Timestamp From a UUID (v1, v6 and v7)

By SimpleTools24Published 3 min read

You can get a timestamp from a UUID only if it's a time-based version: v1, v6 or v7. For a v7 UUID, the first 12 hex digits are a Unix timestamp in milliseconds, so converting them from hex gives the time directly. For v1 and v6, the UUID holds a 60-bit count of 100-nanosecond intervals since 15 October 1582, arranged differently in each version. Version 4 UUIDs are random and contain no time information at all.

Which UUIDs Contain a Time?

Which UUID versions contain a timestamp
VersionTimestamp?Format
v1Yes60-bit, 100 ns units since 1582-10-15, low bits first
v2PartialRare DCE variant with part of the time replaced
v3, v5NoHash of a namespace and name
v4NoRandom
v6YesSame 60-bit value as v1, high bits first
v7Yes48-bit Unix milliseconds
v8MaybeCustom layout defined by the vendor

First check the version: it's the 13th hex digit. How to tell a UUID's version explains how to find it.

Reading a UUID v7 Timestamp

Take the first 12 hex digits (the first two groups without the hyphen) and convert to decimal:

text
UUID:      0192f0c1-6a4b-7c3d-9e2f-0a1b2c3d4e5f
Hex time:  0192f0c16a4b
Decimal:   1730616060491 milliseconds since 1970-01-01 UTC
Date:      2024-11-03 06:41:00.491 UTC

In JavaScript:

javascript
const uuid = '0192f0c1-6a4b-7c3d-9e2f-0a1b2c3d4e5f';
const ms = parseInt(uuid.replace(/-/g, '').slice(0, 12), 16);
console.log(new Date(ms).toISOString()); // 2024-11-03T06:41:00.491Z

In PostgreSQL 17 or later, uuid_extract_timestamp() works for v1, and from PostgreSQL 18 also for v7; see UUID v7 in PostgreSQL.

Reading a UUID v1 Timestamp

Version 1 splits its 60-bit timestamp into three fields and stores the low part first:

text
f81d4fae-7dec-11d0-a765-00a0c91e6bf6
time_low = f81d4fae
time_mid = 7dec
time_hi  = 1d0   (the "1" before it is the version)

Reassemble them high to low, 1d0 + 7dec + f81d4fae, giving 0x1d07decf81d4fae. That's 130,742,845,922,168,750 intervals of 100 ns since 15 October 1582, which works out to 3 February 1997, 17:43:12 UTC. (This is the example UUID from the original specification.)

In Python, the uuid module does the arithmetic:

python
import uuid, datetime

u = uuid.UUID('f81d4fae-7dec-11d0-a765-00a0c91e6bf6')
start = datetime.datetime(1582, 10, 15, tzinfo=datetime.timezone.utc)
print(start + datetime.timedelta(microseconds=u.time // 10))

Why 1582? It's the start of the Gregorian calendar, the epoch chosen in the original DCE design.

Reading a UUID v6 Timestamp

Version 6 stores the same 60-bit Gregorian timestamp as v1, but with the most significant bits first, so v6 values sort by time. To decode, take the first 12 hex digits plus the three hex digits after the version digit, in order, and apply the same 1582 epoch.

What the Timestamp Tells You (and What It Doesn't)

The embedded time is the generator's clock reading when the UUID was created. That's usually close to when a record was made, but:

  • The generating machine's clock may have been wrong.
  • An ID can be generated well before the record is saved, or reused later.
  • Some libraries let callers supply any timestamp, and PostgreSQL's uuidv7() accepts a shift.
  • v1 and v6 generators may adjust values to avoid duplicates.

Treat it as a useful hint for debugging and log analysis, not as proof of when something happened. Store a real created_at column for anything that matters.

Privacy Implications

Because v1, v6 and v7 reveal creation times, exposing them publicly can leak information, such as when an account was opened. v1 can also reveal a hardware address; UUID v1 and MAC address privacy explains that risk. For public identifiers where timing is sensitive, random v4 is the safer choice.

Decode Without Doing the Maths

The UUID decoder reads any UUID and, for v1, v6 and v7, shows the embedded timestamp along with the version, variant and canonical form. For v1 and v6 it also shows the clock sequence and node fields. It runs in your browser. To create v7 values to experiment with, use the UUID v7 generator; to check a batch for validity first, the UUID validator handles up to 1,000 lines.

Frequently Asked Questions

Can I get a date from a UUID v4?

No. A v4 UUID is random apart from its version and variant bits.

What time zone is the UUID timestamp in?

Both v1/v6 and v7 timestamps are based on UTC.

How precise is a v7 timestamp?

Milliseconds. Some implementations add extra sub-millisecond precision in the following bits, but that's optional.

Does the timestamp show when a database row was created?

Only approximately, and only if the ID was generated at insert time on a machine with a correct clock.

Summary

Check the version first. For v7, convert the first 12 hex digits from milliseconds; for v1 and v6, rebuild the 60-bit Gregorian timestamp. Treat the result as a hint, and remember v4 has no time at all.

Sources