RFC Errata


Errata Search

 
Source of RFC  
Summary Table Full Records

RFC 9562, "Universally Unique IDentifiers (UUIDs)", May 2024

Source of RFC: uuidrev (art)
See Also: RFC 9562 w/ inline errata

Errata ID: 8288
Status: Verified
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: Nathan McGarvey
Date Reported: 2025-02-08
Verifier Name: Orie Steele
Date Verified: 2025-02-24

Section 6.1 says:

   Length:
      The length of a given timestamp directly impacts how many
      timestamp ticks can be contained in a UUID before the maximum
      value for the timestamp field is reached.  Take care to ensure
      that the proper length is selected for a given timestamp.  UUIDv1
      and UUIDv6 utilize a 60-bit timestamp valid until 5623 AD; UUIDv7
      features a 48-bit timestamp valid until the year 10889 AD.

It should say:

   Length:
      The length of a given timestamp directly impacts how many
      timestamp ticks can be contained in a UUID before the maximum
      value for the timestamp field is reached.  Take care to ensure
      that the proper length is selected for a given timestamp.  UUIDv1
      and UUIDv6 utilize a 60-bit timestamp valid until 5236 AD; UUIDv7
      features a 48-bit timestamp valid until the year 10889 AD.

Notes:

I believe the error is the result of a bad calculation that used the Unix epoch as the zero-date instead of the Gregorian calendar's 1582 zero-date. I've seen online references to the following [incorrect] calculation for determining the UUIDv1 maximum date: (2^60 / 10^7 / 60 / 60 / 24 / 365.25 + 1970) = 5623.38778807. Source: https://github.com/uuid6/uuid6-ietf-draft/issues/23#issuecomment-898866487

That is: (bitsOfTimeData / 100 nanoseconds / secondsPerMin / minutesPerHour / hoursPerDay / daysPerYear + unixEpochYear). However, the max date for v1 and v6 is based, not on the Unix epoch year, but on the year 1582 (Ref: section 5.1).


The same calculation, but using 1582 as the trailing year added, is 5235.38778807.




Doing manual math approximation:

60 bits = 2^60 = 1152921504606846976 one-hundred-nano-second-intervals
1152921504606846976 * 100 = 115292150460684697600 nanoseconds

115292150460684697600 nanoseconds / 31557600000000000 nanosecondPerYear (365.25 daysPerYear assumed) =~ 3653.3878 years.

Date math: 1582.7890 + 3653.3878 years = 5236.1768 =~ March of 5236




Exact date math spot checking using a couple of programming languages calculators:

Go:

package main

import (
"fmt"
"time"
)

func main() {
t := time.Date(1582, 10, 15, 0, 0, 0, 0, time.UTC)
for _ = range 100 {
t = t.Add(1152921504606846976)
}
fmt.Println(t)
}


Output: 5236-03-31 21:21:00.6846976 +0000 UTC



Python:

from datetime import datetime, timedelta, timezone

start_date = datetime(1582, 10, 15, tzinfo=timezone.utc)

nanoseconds = 115292150460684697600
seconds = nanoseconds // 1_000_000_000 # Convert to seconds
remaining_nanoseconds = nanoseconds % 1_000_000_000
microseconds = remaining_nanoseconds // 1000 # Convert remaining to microseconds

delta = timedelta(seconds=seconds, microseconds=microseconds)

result_date = start_date + delta

print(result_date)


Output: 5236-03-31 21:21:00.684697+00:00



Javascript:

const startDate = new Date(Date.UTC(1582, 9, 15)); // Month is 0-based in JS
const nanoseconds = BigInt('115292150460684697600');

const milliseconds = Number(nanoseconds / BigInt(1_000_000));

const resultDate = new Date(startDate.getTime() + milliseconds);

console.log(resultDate.toUTCString());


Output: Mon, 31 Mar 5236 21:21:00 GMT

Report New Errata



Advanced Search