From c297f8ee96bce394fab1df48d203c1287b1f428a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 22 Dec 2022 20:09:25 +0100 Subject: [PATCH] =?utf8?q?feat(appframework):=20=E2=8C=9A=20Make=20ITimeFa?= =?utf8?q?ctory=20extend=20\PSR\Clock\ClockInterface?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Joas Schilling --- .../AppFramework/Utility/TimeFactory.php | 26 +++++++++- lib/private/Server.php | 1 + .../AppFramework/Utility/ITimeFactory.php | 22 +++++++-- .../AppFramework/Utility/TimeFactoryTest.php | 49 +++++++++++++++++++ 4 files changed, 94 insertions(+), 4 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 27117ed3cfc..1e4655dd1cd 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 @@ -30,11 +31,23 @@ namespace OC\AppFramework\Utility; use OCP\AppFramework\Utility\ITimeFactory; /** - * Needed to mock calls to time() + * Use this to get a timestamp or DateTime object in code to remain testable + * + * @since 8.0.0 + * @since 26.0.0 Extends the \Psr\Clock\ClockInterface interface + * @ref https://www.php-fig.org/psr/psr-20/#21-clockinterface */ class TimeFactory implements ITimeFactory { + protected \DateTimeZone $timezone; + + public function __construct() { + $this->timezone = new \DateTimeZone('UTC'); + } + /** * @return int the result of a call to time() + * @since 8.0.0 + * @deprecated 26.0.0 {@see ITimeFactory::now()} */ public function getTime(): int { return time(); @@ -45,8 +58,19 @@ class TimeFactory implements ITimeFactory { * @param \DateTimeZone $timezone * @return \DateTime * @since 15.0.0 + * @deprecated 26.0.0 {@see ITimeFactory::now()} */ 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 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 fbb86711b41..f9fc585e74d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -1387,6 +1387,7 @@ class Server extends ServerContainer implements IServerContainer { $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 92101fd3848..7a6acf97b2d 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,22 +27,37 @@ declare(strict_types=1); */ namespace OCP\AppFramework\Utility; +use Psr\Clock\ClockInterface; + /** - * Needed to mock calls to time() + * Use this to get a timestamp or DateTime object in code to remain testable + * * @since 8.0.0 + * @since 26.0.0 Extends the \Psr\Clock\ClockInterface interface + * @ref https://www.php-fig.org/psr/psr-20/#21-clockinterface */ -interface ITimeFactory { + +interface ITimeFactory extends ClockInterface { /** * @return int the result of a call to time() * @since 8.0.0 + * @deprecated 26.0.0 {@see ITimeFactory::now()} */ public function getTime(): int; /** * @param string $time - * @param \DateTimeZone $timezone + * @param \DateTimeZone|null $timezone * @return \DateTime * @since 15.0.0 + * @deprecated 26.0.0 {@see ITimeFactory::now()} */ public function getDateTime(string $time = 'now', \DateTimeZone $timezone = null): \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 00000000000..5811a2cf86a --- /dev/null +++ b/tests/lib/AppFramework/Utility/TimeFactoryTest.php @@ -0,0 +1,49 @@ + + * + * @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 testNowWithTimeZone(): void { + $timezone = new \DateTimeZone('Europe/Berlin'); + $withTimeZone = $this->timeFactory->withTimeZone($timezone); + + $now = $withTimeZone->now(); + self::assertSame('Europe/Berlin', $now->getTimezone()->getName()); + } +} -- 2.39.5