diff --git a/UPGRADE-5.3.md b/UPGRADE-5.3.md index 2a59bd730d..707e5d26dd 100644 --- a/UPGRADE-5.3.md +++ b/UPGRADE-5.3.md @@ -4,24 +4,24 @@ UPGRADE FROM 5.2 to 5.3 Asset ----- - * Deprecated `RemoteJsonManifestVersionStrategy`, use `JsonManifestVersionStrategy` instead. + * Deprecated `RemoteJsonManifestVersionStrategy`, use `JsonManifestVersionStrategy` instead DomCrawler ---------- -* Deprecated the `parents()` method, use `ancestors()` instead. + * Deprecated the `parents()` method, use `ancestors()` instead Form ---- - * Changed `$forms` parameter type of the `DataMapperInterface::mapDataToForms()` method from `iterable` to `\Traversable`. - * Changed `$forms` parameter type of the `DataMapperInterface::mapFormsToData()` method from `iterable` to `\Traversable`. - * Deprecated passing an array as the second argument of the `DataMapper::mapDataToForms()` method, pass `\Traversable` instead. - * Deprecated passing an array as the first argument of the `DataMapper::mapFormsToData()` method, pass `\Traversable` instead. - * Deprecated passing an array as the second argument of the `CheckboxListMapper::mapDataToForms()` method, pass `\Traversable` instead. - * Deprecated passing an array as the first argument of the `CheckboxListMapper::mapFormsToData()` method, pass `\Traversable` instead. - * Deprecated passing an array as the second argument of the `RadioListMapper::mapDataToForms()` method, pass `\Traversable` instead. - * Deprecated passing an array as the first argument of the `RadioListMapper::mapFormsToData()` method, pass `\Traversable` instead. + * Changed `$forms` parameter type of the `DataMapperInterface::mapDataToForms()` method from `iterable` to `\Traversable` + * Changed `$forms` parameter type of the `DataMapperInterface::mapFormsToData()` method from `iterable` to `\Traversable` + * Deprecated passing an array as the second argument of the `DataMapper::mapDataToForms()` method, pass `\Traversable` instead + * Deprecated passing an array as the first argument of the `DataMapper::mapFormsToData()` method, pass `\Traversable` instead + * Deprecated passing an array as the second argument of the `CheckboxListMapper::mapDataToForms()` method, pass `\Traversable` instead + * Deprecated passing an array as the first argument of the `CheckboxListMapper::mapFormsToData()` method, pass `\Traversable` instead + * Deprecated passing an array as the second argument of the `RadioListMapper::mapDataToForms()` method, pass `\Traversable` instead + * Deprecated passing an array as the first argument of the `RadioListMapper::mapFormsToData()` method, pass `\Traversable` instead HttpFoundation -------------- @@ -36,29 +36,37 @@ HttpKernel Messenger --------- -* Deprecated the `prefetch_count` parameter in the AMQP bridge, it has no effect and will be removed in Symfony 6.0. + * Deprecated the `prefetch_count` parameter in the AMQP bridge, it has no effect and will be removed in Symfony 6.0 Notifier -------- +-------- + + * Changed the return type of `AbstractTransportFactory::getEndpoint()` from `?string` to `string` + * Changed the signature of `Dsn::__construct()` to accept a single `string $dsn` argument + * Removed the `Dsn::fromString()` method -* Changed the return type of `Symfony\Component\Notifier\Transport\AbstractTransportFactory::getEndpoint()` from `?string` to `string` PhpunitBridge ------------- - * Deprecated the `SetUpTearDownTrait` trait, use original methods with "void" return typehint. + * Deprecated the `SetUpTearDownTrait` trait, use original methods with "void" return typehint PropertyInfo ------------ -* Deprecated the `Type::getCollectionKeyType()` and `Type::getCollectionValueType()` methods, use `Type::getCollectionKeyTypes()` and `Type::getCollectionValueTypes()` instead. + * Deprecated the `Type::getCollectionKeyType()` and `Type::getCollectionValueType()` methods, use `Type::getCollectionKeyTypes()` and `Type::getCollectionValueTypes()` instead Security -------- - * Deprecated voters that do not return a valid decision when calling the `vote` method. + * Deprecated voters that do not return a valid decision when calling the `vote` method Serializer ---------- - * Deprecated `ArrayDenormalizer::setSerializer()`, call `setDenormalizer()` instead. + * Deprecated `ArrayDenormalizer::setSerializer()`, call `setDenormalizer()` instead + +Uid +--- + + * Replaced `UuidV1::getTime()`, `UuidV6::getTime()` and `Ulid::getTime()` by `UuidV1::getDateTime()`, `UuidV6::getDateTime()` and `Ulid::getDateTime()` diff --git a/src/Symfony/Component/Uid/BinaryUtil.php b/src/Symfony/Component/Uid/BinaryUtil.php index 5e9741cbea..f9ef273d48 100644 --- a/src/Symfony/Component/Uid/BinaryUtil.php +++ b/src/Symfony/Component/Uid/BinaryUtil.php @@ -119,10 +119,10 @@ class BinaryUtil /** * @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 + public static function timeToDateTime(string $time): \DateTimeImmutable { if (\PHP_INT_SIZE >= 8) { - $time = hexdec($time) - self::TIME_OFFSET_INT; + $time = (string) (hexdec($time) - self::TIME_OFFSET_INT); } else { $time = str_pad(hex2bin($time), 8, "\0", \STR_PAD_LEFT); @@ -136,6 +136,10 @@ class BinaryUtil } } - return $time / 10000000; + if (9 > \strlen($time)) { + $time = '-' === $time[0] ? '-'.str_pad(substr($time, 1), 8, '0', \STR_PAD_LEFT) : str_pad($time, 8, '0', \STR_PAD_LEFT); + } + + return \DateTimeImmutable::createFromFormat('U.u?', substr_replace($time, '.', -7, 0)); } } diff --git a/src/Symfony/Component/Uid/CHANGELOG.md b/src/Symfony/Component/Uid/CHANGELOG.md index d81459ce75..69eb0a2f42 100644 --- a/src/Symfony/Component/Uid/CHANGELOG.md +++ b/src/Symfony/Component/Uid/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Add `AbstractUid::fromBinary()`, `AbstractUid::fromBase58()`, `AbstractUid::fromBase32()` and `AbstractUid::fromRfc4122()` + * [BC BREAK] Replace `UuidV1::getTime()`, `UuidV6::getTime()` and `Ulid::getTime()` by `UuidV1::getDateTime()`, `UuidV6::getDateTime()` and `Ulid::getDateTime()` 5.2.0 ----- diff --git a/src/Symfony/Component/Uid/Tests/UlidTest.php b/src/Symfony/Component/Uid/Tests/UlidTest.php index c7603bafc4..3a5d58926f 100644 --- a/src/Symfony/Component/Uid/Tests/UlidTest.php +++ b/src/Symfony/Component/Uid/Tests/UlidTest.php @@ -76,13 +76,18 @@ class UlidTest extends TestCase /** * @group time-sensitive */ - public function testGetTime() + public function testGetDateTime() { $time = microtime(false); $ulid = new Ulid(); $time = substr($time, 11).substr($time, 1, 4); - $this->assertSame((float) $time, $ulid->getTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', $time), $ulid->getDateTime()); + + $this->assertEquals(new \DateTimeImmutable('@0'), (new Ulid('000000000079KA1307SR9X4MV3'))->getDateTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '0.001'), (new Ulid('000000000179KA1307SR9X4MV3'))->getDateTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '281474976710.654'), (new Ulid('7ZZZZZZZZY79KA1307SR9X4MV3'))->getDateTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '281474976710.655'), (new Ulid('7ZZZZZZZZZ79KA1307SR9X4MV3'))->getDateTime()); } public function testIsValid() diff --git a/src/Symfony/Component/Uid/Tests/UuidTest.php b/src/Symfony/Component/Uid/Tests/UuidTest.php index cdb8614b6b..2903eda771 100644 --- a/src/Symfony/Component/Uid/Tests/UuidTest.php +++ b/src/Symfony/Component/Uid/Tests/UuidTest.php @@ -60,7 +60,7 @@ class UuidTest extends TestCase $uuid = new UuidV1(self::A_UUID_V1); - $this->assertSame(1583245966.746458, $uuid->getTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '1583245966.746458'), $uuid->getDateTime()); $this->assertSame('3499710062d0', $uuid->getNode()); } @@ -95,7 +95,7 @@ class UuidTest extends TestCase $uuid = new UuidV6(substr_replace(self::A_UUID_V1, '6', 14, 1)); - $this->assertSame(85916308548.27832, $uuid->getTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '85916308548.278321'), $uuid->getDateTime()); $this->assertSame('3499710062d0', $uuid->getNode()); } @@ -308,12 +308,14 @@ class UuidTest extends TestCase $this->assertInstanceOf(CustomUuid::class, CustomUuid::fromString(self::A_UUID_V4)); } - public function testGetTime() + public function testGetDateTime() { - $this->assertSame(103072857660.6847, ((new UuidV1('ffffffff-ffff-1fff-a456-426655440000'))->getTime())); - $this->assertSame(0.0000001, ((new UuidV1('13814001-1dd2-11b2-a456-426655440000'))->getTime())); - $this->assertSame(0.0, (new UuidV1('13814000-1dd2-11b2-a456-426655440000'))->getTime()); - $this->assertSame(-0.0000001, (new UuidV1('13813fff-1dd2-11b2-a456-426655440000'))->getTime()); - $this->assertSame(-12219292800.0, ((new UuidV1('00000000-0000-1000-a456-426655440000'))->getTime())); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '103072857660.684697'), ((new UuidV1('ffffffff-ffff-1fff-a456-426655440000'))->getDateTime())); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '0.000001'), ((new UuidV1('1381400a-1dd2-11b2-a456-426655440000'))->getDateTime())); + $this->assertEquals(new \DateTimeImmutable('@0'), (new UuidV1('13814001-1dd2-11b2-a456-426655440000'))->getDateTime()); + $this->assertEquals(new \DateTimeImmutable('@0'), (new UuidV1('13814000-1dd2-11b2-a456-426655440000'))->getDateTime()); + $this->assertEquals(new \DateTimeImmutable('@0'), (new UuidV1('13813fff-1dd2-11b2-a456-426655440000'))->getDateTime()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('U.u', '-0.000001'), ((new UuidV1('13813ff6-1dd2-11b2-a456-426655440000'))->getDateTime())); + $this->assertEquals(new \DateTimeImmutable('@-12219292800'), ((new UuidV1('00000000-0000-1000-a456-426655440000'))->getDateTime())); } } diff --git a/src/Symfony/Component/Uid/Ulid.php b/src/Symfony/Component/Uid/Ulid.php index 959f41657f..4fd487ad02 100644 --- a/src/Symfony/Component/Uid/Ulid.php +++ b/src/Symfony/Component/Uid/Ulid.php @@ -104,24 +104,26 @@ class Ulid extends AbstractUid return $this->uid; } - /** - * @return float Seconds since the Unix epoch 1970-01-01 00:00:00 - */ - public function getTime(): float + public function getDateTime(): \DateTimeImmutable { $time = strtr(substr($this->uid, 0, 10), 'ABCDEFGHJKMNPQRSTVWXYZ', 'abcdefghijklmnopqrstuv'); if (\PHP_INT_SIZE >= 8) { - return hexdec(base_convert($time, 32, 16)) / 1000; + $time = (string) hexdec(base_convert($time, 32, 16)); + } else { + $time = sprintf('%02s%05s%05s', + base_convert(substr($time, 0, 2), 32, 16), + base_convert(substr($time, 2, 4), 32, 16), + base_convert(substr($time, 6, 4), 32, 16) + ); + $time = BinaryUtil::toBase(hex2bin($time), BinaryUtil::BASE10); } - $time = sprintf('%02s%05s%05s', - base_convert(substr($time, 0, 2), 32, 16), - base_convert(substr($time, 2, 4), 32, 16), - base_convert(substr($time, 6, 4), 32, 16) - ); + if (4 > \strlen($time)) { + $time = str_pad($time, 4, '0', \STR_PAD_LEFT); + } - return BinaryUtil::toBase(hex2bin($time), BinaryUtil::BASE10) / 1000; + return \DateTimeImmutable::createFromFormat('U.u', substr_replace($time, '.', -3, 0)); } private static function generate(): string diff --git a/src/Symfony/Component/Uid/UuidV1.php b/src/Symfony/Component/Uid/UuidV1.php index 2710a9db49..769a00ca69 100644 --- a/src/Symfony/Component/Uid/UuidV1.php +++ b/src/Symfony/Component/Uid/UuidV1.php @@ -31,14 +31,9 @@ class UuidV1 extends Uuid } } - /** - * @return float Seconds since the Unix epoch 1970-01-01 00:00:00 - */ - public function getTime(): float + public function getDateTime(): \DateTimeImmutable { - $time = '0'.substr($this->uid, 15, 3).substr($this->uid, 9, 4).substr($this->uid, 0, 8); - - return BinaryUtil::timeToFloat($time); + return BinaryUtil::timeToDateTime('0'.substr($this->uid, 15, 3).substr($this->uid, 9, 4).substr($this->uid, 0, 8)); } public function getNode(): string diff --git a/src/Symfony/Component/Uid/UuidV6.php b/src/Symfony/Component/Uid/UuidV6.php index 79cab4c15c..cb3ff6639c 100644 --- a/src/Symfony/Component/Uid/UuidV6.php +++ b/src/Symfony/Component/Uid/UuidV6.php @@ -50,14 +50,9 @@ class UuidV6 extends Uuid } } - /** - * @return float Seconds since the Unix epoch 1970-01-01 00:00:00 - */ - public function getTime(): float + public function getDateTime(): \DateTimeImmutable { - $time = '0'.substr($this->uid, 0, 8).substr($this->uid, 9, 4).substr($this->uid, 15, 3); - - return BinaryUtil::timeToFloat($time); + return BinaryUtil::timeToDateTime('0'.substr($this->uid, 0, 8).substr($this->uid, 9, 4).substr($this->uid, 15, 3)); } public function getNode(): string