Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 08bb79b

Browse filesBrowse files
minor #36053 [Uid] make Uuid::getTime() return subseconds info (nicolas-grekas)
This PR was merged into the 5.1-dev branch. Discussion ---------- [Uid] make Uuid::getTime() return subseconds info | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - A UUID timestamp contains 60bit of data, but a timestamp barely contains 31bit. Let's return a float instead. Commits ------- 5a170b8 [Uid] make Uuid::getTime() return subseconds info
2 parents d028a50 + 5a170b8 commit 08bb79b
Copy full SHA for 08bb79b

3 files changed

+104-3Lines changed: 104 additions & 3 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file
+85Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid;
13+
14+
/**
15+
* @internal
16+
*
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
class InternalUtil
20+
{
21+
public static function toBinary(string $digits): string
22+
{
23+
$bytes = '';
24+
$len = \strlen($digits);
25+
26+
while ($len > $i = strspn($digits, '0')) {
27+
for ($j = 2, $r = 0; $i < $len; $i += $j, $j = 0) {
28+
do {
29+
$r *= 10;
30+
$d = (int) substr($digits, $i, ++$j);
31+
} while ($i + $j < $len && $r + $d < 256);
32+
33+
$j = \strlen((string) $d);
34+
$q = str_pad(($d += $r) >> 8, $j, '0', STR_PAD_LEFT);
35+
$digits = substr_replace($digits, $q, $i, $j);
36+
$r = $d % 256;
37+
}
38+
39+
$bytes .= \chr($r);
40+
}
41+
42+
return strrev($bytes);
43+
}
44+
45+
public static function toDecimal(string $bytes): string
46+
{
47+
$digits = '';
48+
$len = \strlen($bytes);
49+
50+
while ($len > $i = strspn($bytes, "\0")) {
51+
for ($r = 0; $i < $len; $i += $j) {
52+
$j = $d = 0;
53+
do {
54+
$r <<= 8;
55+
$d = ($d << 8) + \ord($bytes[$i + $j]);
56+
} while ($i + ++$j < $len && $r + $d < 10);
57+
58+
if (256 < $d) {
59+
$q = intdiv($d += $r, 10);
60+
$bytes[$i] = \chr($q >> 8);
61+
$bytes[1 + $i] = \chr($q & 0xFF);
62+
} else {
63+
$bytes[$i] = \chr(intdiv($d += $r, 10));
64+
}
65+
$r = $d % 10;
66+
}
67+
68+
$digits .= (string) $r;
69+
}
70+
71+
return strrev($digits);
72+
}
73+
74+
public static function binaryAdd(string $a, string $b): string
75+
{
76+
$sum = 0;
77+
for ($i = 7; 0 <= $i; --$i) {
78+
$sum += \ord($a[$i]) + \ord($b[$i]);
79+
$a[$i] = \chr($sum & 0xFF);
80+
$sum >>= 8;
81+
}
82+
83+
return $a;
84+
}
85+
}
Collapse file

‎src/Symfony/Component/Uid/Tests/UuidTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Uid/Tests/UuidTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function testExtraMethods()
117117
$uuid = new Uuid(self::A_UUID_V1);
118118

119119
$this->assertSame(Uuid::VARIANT_DCE, $uuid->getVariant());
120-
$this->assertSame(1583245966, $uuid->getTime());
120+
$this->assertSame(1583245966.746458, $uuid->getTime());
121121
$this->assertSame('3499710062d0', $uuid->getMac());
122122
$this->assertSame(self::A_UUID_V1, (string) $uuid);
123123
}
Collapse file

‎src/Symfony/Component/Uid/Uuid.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Uid/Uuid.php
+18-2Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ class Uuid implements \JsonSerializable
2828
public const VARIANT_MICROSOFT = UUID_VARIANT_MICROSOFT;
2929
public const VARIANT_OTHER = UUID_VARIANT_OTHER;
3030

31+
// https://tools.ietf.org/html/rfc4122#section-4.1.4
32+
// 0x01b21dd213814000 is the number of 100-ns intervals between the
33+
// UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
34+
private const TIME_OFFSET_INT = 0x01b21dd213814000;
35+
private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
36+
3137
private $uuid;
3238

3339
public function __construct(string $uuid = null)
@@ -105,13 +111,23 @@ public function getVariant(): int
105111
return uuid_variant($this->uuid);
106112
}
107113

108-
public function getTime(): int
114+
public function getTime(): float
109115
{
110116
if (self::TYPE_1 !== $t = uuid_type($this->uuid)) {
111117
throw new \LogicException("UUID of type $t doesn't contain a time.");
112118
}
113119

114-
return uuid_time($this->uuid);
120+
$time = '0'.substr($this->uuid, 15, 3).substr($this->uuid, 9, 4).substr($this->uuid, 0, 8);
121+
122+
if (\PHP_INT_SIZE >= 8) {
123+
return (hexdec($time) - self::TIME_OFFSET_INT) / 10000000;
124+
}
125+
126+
$time = str_pad(hex2bin($time), 8, "\0", STR_PAD_LEFT);
127+
$time = InternalUtil::binaryAdd($time, self::TIME_OFFSET_COM);
128+
$time[0] = $time[0] & "\x7F";
129+
130+
return InternalUtil::toDecimal($time) / 10000000;
115131
}
116132

117133
public function getMac(): string

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.