PluginProbe
Media Cloud Sync / 1.2.4
Media Cloud Sync v1.2.4
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / google / ramsey / uuid / src / Converter / Time / PhpTimeConverter.php

PhpTimeConverter.php in Media Cloud Sync 1.2.4, at includes/sdk/google/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php

139 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the ramsey/uuid library
5 *
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
8 *
9 * @copyright Copyright (c) Ben Ramsey <[email protected]>
10 * @license http://opensource.org/licenses/MIT MIT
11 */
12 declare (strict_types=1);
13 namespace Dudlewebs\WPMCS\Ramsey\Uuid\Converter\Time;
14
15 use Dudlewebs\WPMCS\Ramsey\Uuid\Converter\TimeConverterInterface;
16 use Dudlewebs\WPMCS\Ramsey\Uuid\Math\BrickMathCalculator;
17 use Dudlewebs\WPMCS\Ramsey\Uuid\Math\CalculatorInterface;
18 use Dudlewebs\WPMCS\Ramsey\Uuid\Type\Hexadecimal;
19 use Dudlewebs\WPMCS\Ramsey\Uuid\Type\Integer as IntegerObject;
20 use Dudlewebs\WPMCS\Ramsey\Uuid\Type\Time;
21 use function count;
22 use function dechex;
23 use function explode;
24 use function is_float;
25 use function is_int;
26 use function str_pad;
27 use function strlen;
28 use function substr;
29 use const STR_PAD_LEFT;
30 use const STR_PAD_RIGHT;
31 /**
32 * PhpTimeConverter uses built-in PHP functions and standard math operations
33 * available to the PHP programming language to provide facilities for
34 * converting parts of time into representations that may be used in UUIDs
35 *
36 * @psalm-immutable
37 */
38 class PhpTimeConverter implements TimeConverterInterface
39 {
40 /**
41 * The number of 100-nanosecond intervals from the Gregorian calendar epoch
42 * to the Unix epoch.
43 */
44 private const GREGORIAN_TO_UNIX_INTERVALS = 0x1b21dd213814000;
45 /**
46 * The number of 100-nanosecond intervals in one second.
47 */
48 private const SECOND_INTERVALS = 10000000;
49 /**
50 * The number of 100-nanosecond intervals in one microsecond.
51 */
52 private const MICROSECOND_INTERVALS = 10;
53 /**
54 * @var CalculatorInterface
55 */
56 private $calculator;
57 /**
58 * @var TimeConverterInterface
59 */
60 private $fallbackConverter;
61 /**
62 * @var int
63 */
64 private $phpPrecision;
65 public function __construct(?CalculatorInterface $calculator = null, ?TimeConverterInterface $fallbackConverter = null)
66 {
67 if ($calculator === null) {
68 $calculator = new BrickMathCalculator();
69 }
70 if ($fallbackConverter === null) {
71 $fallbackConverter = new GenericTimeConverter($calculator);
72 }
73 $this->calculator = $calculator;
74 $this->fallbackConverter = $fallbackConverter;
75 $this->phpPrecision = (int) ini_get('precision');
76 }
77 public function calculateTime(string $seconds, string $microseconds): Hexadecimal
78 {
79 $seconds = new IntegerObject($seconds);
80 $microseconds = new IntegerObject($microseconds);
81 // Calculate the count of 100-nanosecond intervals since the Gregorian
82 // calendar epoch for the given seconds and microseconds.
83 $uuidTime = (int) $seconds->toString() * self::SECOND_INTERVALS + (int) $microseconds->toString() * self::MICROSECOND_INTERVALS + self::GREGORIAN_TO_UNIX_INTERVALS;
84 // Check to see whether we've overflowed the max/min integer size.
85 // If so, we will default to a different time converter.
86 /** @psalm-suppress RedundantCondition */
87 if (!is_int($uuidTime)) {
88 return $this->fallbackConverter->calculateTime($seconds->toString(), $microseconds->toString());
89 }
90 return new Hexadecimal(str_pad(dechex($uuidTime), 16, '0', STR_PAD_LEFT));
91 }
92 public function convertTime(Hexadecimal $uuidTimestamp): Time
93 {
94 $timestamp = $this->calculator->toInteger($uuidTimestamp);
95 // Convert the 100-nanosecond intervals into seconds and microseconds.
96 $splitTime = $this->splitTime(((int) $timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) / self::SECOND_INTERVALS);
97 if (count($splitTime) === 0) {
98 return $this->fallbackConverter->convertTime($uuidTimestamp);
99 }
100 return new Time($splitTime['sec'], $splitTime['usec']);
101 }
102 /**
103 * @param int|float $time The time to split into seconds and microseconds
104 *
105 * @return string[]
106 */
107 private function splitTime($time): array
108 {
109 $split = explode('.', (string) $time, 2);
110 // If the $time value is a float but $split only has 1 element, then the
111 // float math was rounded up to the next second, so we want to return
112 // an empty array to allow use of the fallback converter.
113 if (is_float($time) && count($split) === 1) {
114 return [];
115 }
116 if (count($split) === 1) {
117 return ['sec' => $split[0], 'usec' => '0'];
118 }
119 // If the microseconds are less than six characters AND the length of
120 // the number is greater than or equal to the PHP precision, then it's
121 // possible that we lost some precision for the microseconds. Return an
122 // empty array, so that we can choose to use the fallback converter.
123 if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) {
124 return [];
125 }
126 $microseconds = $split[1];
127 // Ensure the microseconds are no longer than 6 digits. If they are,
128 // truncate the number to the first 6 digits and round up, if needed.
129 if (strlen($microseconds) > 6) {
130 $roundingDigit = (int) substr($microseconds, 6, 1);
131 $microseconds = (int) substr($microseconds, 0, 6);
132 if ($roundingDigit >= 5) {
133 $microseconds++;
134 }
135 }
136 return ['sec' => $split[0], 'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT)];
137 }
138 }
139