@@ -134,6 +134,18 @@ private static function uuidFromHex(string $uhex, int $version): string
134134 );
135135 }
136136
137+ /** @internal */
138+ private static function encodeSubsec (int $ value ): int
139+ {
140+ return intdiv ($ value * 2 ** 24 , 10 ** 7 );
141+ }
142+
143+ /** @internal */
144+ private static function decodeSubsec (int $ value ): int
145+ {
146+ return (int ) ceil ($ value * 10 ** 7 / 2 ** 24 );
147+ }
148+
137149 /**
138150 * Generate a version 3 UUID based on the MD5 hash of a namespace identifier
139151 * (which is a UUID) and a name (which is a string).
@@ -201,6 +213,7 @@ public static function uuid6(): string
201213 public static function uuid7 (): string
202214 {
203215 [$ unixts , $ subsec ] = self ::getUnixTime ();
216+ $ subsec = self ::encodeSubsec ($ subsec );
204217 $ uhex = substr (str_pad (dechex ($ unixts ), 9 , '0 ' , \STR_PAD_LEFT ), -9 );
205218 $ uhex .= substr_replace (str_pad (dechex ($ subsec ), 6 , '0 ' , \STR_PAD_LEFT ), '7 ' , -3 , 0 );
206219 $ uhex .= bin2hex (random_bytes (8 ));
@@ -246,7 +259,7 @@ public static function getTime(string $uuid): ?string
246259 $ retval = substr_replace (strval (hexdec ($ timehex ) - self ::TIME_OFFSET_INT ), '. ' , -7 , 0 );
247260 } elseif ($ version === 7 ) {
248261 $ unixts = hexdec (substr ($ timehex , 0 , 10 ));
249- $ subsec = str_pad (strval (hexdec (substr ($ timehex , 10 ))), 7 , '0 ' , \STR_PAD_LEFT );
262+ $ subsec = str_pad (strval (self :: decodeSubsec ( hexdec (substr ($ timehex , 10 ) ))), 7 , '0 ' , \STR_PAD_LEFT );
250263 $ retval = $ unixts . '. ' . $ subsec ;
251264 }
252265 return $ retval ;
0 commit comments