From: Joas Schilling Date: Thu, 22 Dec 2022 19:09:25 +0000 (+0100) Subject: feat(appframework): ⌚ Make ITimeFactory extend \PSR\Clock\ClockInterface X-Git-Tag: v27.0.0beta1~378^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F35872%2Fhead;p=nextcloud-server.git feat(appframework): ⌚ Make ITimeFactory extend \PSR\Clock\ClockInterface Signed-off-by: Joas Schilling --- 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()); + } +}