From 589cf70b2a1ca0787a7129a66c6276a8f7462f89 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 22 Dec 2022 20:09:25 +0100 Subject: [PATCH] =?UTF-8?q?feat(appframework):=20=E2=8C=9A=20Make=20ITimeF?= =?UTF-8?q?actory=20extend=20\PSR\Clock\ClockInterface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Joas Schilling --- .../AppFramework/Utility/TimeFactory.php | 20 +++++++ lib/private/Server.php | 1 + .../AppFramework/Utility/ITimeFactory.php | 22 +++++++- .../AppFramework/Utility/TimeFactoryTest.php | 54 +++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/lib/AppFramework/Utility/TimeFactoryTest.php diff --git a/lib/private/AppFramework/Utility/TimeFactory.php b/lib/private/AppFramework/Utility/TimeFactory.php index d4fe451a995e8..3a7a1df318273 100644 --- a/lib/private/AppFramework/Utility/TimeFactory.php +++ b/lib/private/AppFramework/Utility/TimeFactory.php @@ -3,6 +3,7 @@ declare(strict_types=1); /** + * @copyright Copyright (c) 2022, Joas Schilling * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Bernhard Posselt @@ -33,7 +34,11 @@ * Needed to mock calls to time() */ class TimeFactory implements ITimeFactory { + protected \DateTimeZone $timezone; + public function __construct() { + $this->timezone = new \DateTimeZone('UTC'); + } /** * @return int the result of a call to time() @@ -51,4 +56,19 @@ public function getTime(): int { public function getDateTime(string $time = 'now', \DateTimeZone $timezone = null): \DateTime { return new \DateTime($time, $timezone); } + + public function now(): \DateTimeImmutable { + return new \DateTimeImmutable('now', $this->timezone); + } + + public function nowMutable(): \DateTime { + return \DateTime::createFromImmutable($this->now()); + } + + public function withTimeZone(\DateTimeZone $timezone): static { + $clone = clone $this; + $clone->timezone = $timezone; + + return $clone; + } } diff --git a/lib/private/Server.php b/lib/private/Server.php index d420b6fd11d7d..108319d326150 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -1388,6 +1388,7 @@ public function __construct($webRoot, \OC\Config $config) { $this->registerDeprecatedAlias('ControllerMethodReflector', \OCP\AppFramework\Utility\IControllerMethodReflector::class); $this->registerAlias(\OCP\AppFramework\Utility\ITimeFactory::class, \OC\AppFramework\Utility\TimeFactory::class); + $this->registerAlias(\Psr\Clock\ClockInterface::class, \OCP\AppFramework\Utility\ITimeFactory::class); /** @deprecated 19.0.0 */ $this->registerDeprecatedAlias('TimeFactory', \OCP\AppFramework\Utility\ITimeFactory::class); diff --git a/lib/public/AppFramework/Utility/ITimeFactory.php b/lib/public/AppFramework/Utility/ITimeFactory.php index 63a87cf1b16a0..529584bba5e08 100644 --- a/lib/public/AppFramework/Utility/ITimeFactory.php +++ b/lib/public/AppFramework/Utility/ITimeFactory.php @@ -3,6 +3,7 @@ declare(strict_types=1); /** + * @copyright Copyright (c) 2022, Joas Schilling * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Bernhard Posselt @@ -26,11 +27,15 @@ */ namespace OCP\AppFramework\Utility; +use Psr\Clock\ClockInterface; + /** * Needed to mock calls to time() + * * @since 8.0.0 + * @since 26.0.0 Extends the \Psr\Clock\ClockInterface interface */ -interface ITimeFactory { +interface ITimeFactory extends ClockInterface { /** * @return int the result of a call to time() @@ -40,9 +45,22 @@ public function getTime(): int; /** * @param string $time - * @param \DateTimeZone $timezone + * @param \DateTimeZone|null $timezone * @return \DateTime * @since 15.0.0 */ public function getDateTime(string $time = 'now', \DateTimeZone $timezone = null): \DateTime; + + /** + * @return \DateTime + * @since 26.0.0 + */ + public function nowMutable(): \DateTime; + + /** + * @param \DateTimeZone $timezone + * @return static + * @since 26.0.0 + */ + public function withTimeZone(\DateTimeZone $timezone): static; } diff --git a/tests/lib/AppFramework/Utility/TimeFactoryTest.php b/tests/lib/AppFramework/Utility/TimeFactoryTest.php new file mode 100644 index 0000000000000..1da3e283d40ac --- /dev/null +++ b/tests/lib/AppFramework/Utility/TimeFactoryTest.php @@ -0,0 +1,54 @@ + + * + * @author Joas Schilling + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace Test\AppFramework\Utility; + +use OC\AppFramework\Utility\TimeFactory; + +class TimeFactoryTest extends \Test\TestCase { + protected TimeFactory $timeFactory; + + protected function setUp(): void { + $this->timeFactory = new TimeFactory(); + } + + public function testNow(): void { + $now = $this->timeFactory->now(); + self::assertSame('UTC', $now->getTimezone()->getName()); + } + + public function testNowMutable(): void { + $now = $this->timeFactory->nowMutable(); + self::assertSame('UTC', $now->getTimezone()->getName()); + } + + public function testNowWithTimeZone(): void { + $timezone = new \DateTimeZone('Europe/Berlin'); + $withTimeZone = $this->timeFactory->withTimeZone($timezone); + + $now = $withTimeZone->now(); + self::assertSame('Europe/Berlin', $now->getTimezone()->getName()); + } +}