[Uid] improve logic in BinaryUtil::timeToFloat()

This commit is contained in:
Nicolas Grekas 2021-01-27 21:47:53 +01:00
parent bdf3589918
commit 85558248e6

View File

@ -40,6 +40,8 @@ class BinaryUtil
// 0x01b21dd213814000 is the number of 100-ns intervals between the
// UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
private const TIME_OFFSET_INT = 0x01b21dd213814000;
private const TIME_OFFSET_BIN = "\x01\xb2\x1d\xd2\x13\x81\x40\x00";
private const TIME_OFFSET_COM1 = "\xfe\x4d\xe2\x2d\xec\x7e\xbf\xff";
private const TIME_OFFSET_COM2 = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
public static function toBase(string $bytes, array $map): string
@ -114,20 +116,24 @@ class BinaryUtil
return $a;
}
/**
* @param string $time Count of 100-nanosecond intervals since the UUID epoch 1582-10-15 00:00:00 in hexadecimal
*/
public static function timeToFloat(string $time): float
{
if (\PHP_INT_SIZE >= 8) {
return (hexdec($time) - self::TIME_OFFSET_INT) / 10000000;
}
$time = str_pad(hex2bin($time), 8, "\0", \STR_PAD_LEFT);
$time = self::add($time, self::TIME_OFFSET_COM2);
if ($time >= self::TIME_OFFSET_COM2) {
$time = -1 * (self::toBase($time ^ "\xff\xff\xff\xff\xff\xff\xff\xff", self::BASE10) + 1);
$time = hexdec($time) - self::TIME_OFFSET_INT;
} else {
$time[0] = $time[0] & "\x7F";
$time = self::toBase($time, self::BASE10);
$time = str_pad(hex2bin($time), 8, "\0", \STR_PAD_LEFT);
if (self::TIME_OFFSET_BIN <= $time) {
$time = self::add($time, self::TIME_OFFSET_COM2);
$time[0] = $time[0] & "\x7F";
$time = self::toBase($time, self::BASE10);
} else {
$time = self::add($time, self::TIME_OFFSET_COM1);
$time = '-'.self::toBase($time ^ "\xff\xff\xff\xff\xff\xff\xff\xff", self::BASE10);
}
}
return $time / 10000000;