diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d827aee..5e416b1 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -17,7 +17,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.4 coverage: none - name: Get composer cache directory @@ -52,7 +52,7 @@ jobs: uses: shivammathur/setup-php@v2 with: coverage: none - php-version: 8.2 + php-version: 8.4 - name: Get composer cache directory id: composer-cache @@ -77,7 +77,7 @@ jobs: strategy: matrix: - php-versions: ['8.0', '8.1', '8.2'] + php-versions: ['8.3', '8.4'] steps: - name: Checkout code @@ -104,7 +104,7 @@ jobs: run: composer install --no-interaction --no-progress --prefer-dist --optimize-autoloader - name: Run unit tests - run: ./vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml --coverage-text + run: ./vendor/bin/phpunit - name: Publish coverage report to Codecov uses: codecov/codecov-action@v1 diff --git a/composer.json b/composer.json index 8accd39..0b00533 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "name": "pauci/datetime", "description": "Enhanced DateTime, DateTimeImmutable and DateInterval objects", + "version": "0.7.0", "type": "library", "keywords": [ "datetime", @@ -22,7 +23,7 @@ "issues": "https://github.com/pauci/datetime/issues" }, "require": { - "php": "^8.0 || ^8.1 || ^8.2", + "php": "^8.3 || ^8.4", "ext-json": "*", "psr/clock": "^1.0" }, @@ -31,7 +32,8 @@ "phpstan/extension-installer": "^1.2", "phpstan/phpstan": "^1.9", "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^11.0.0", + "rector/rector": "^1.2", "squizlabs/php_codesniffer": "^3.7" }, "suggest": { @@ -57,12 +59,16 @@ "check": [ "@lint", "@cs-check", + "@rector", "@stan", "@test" ], "lint": "parallel-lint src tests", "cs-check": "phpcs", "cs-fix": "phpcbf", + "rector": "rector -n -vv", + "rector:clear": "rector -n --clear-cache -vv", + "rector:fix": "rector -vv", "stan": "phpstan analyse --no-progress", "test": "phpunit", "test-coverage": "phpunit --coverage-clover clover.xml" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a686948..ed19b24 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,10 @@ - + ./src diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..8bfdc87 --- /dev/null +++ b/rector.php @@ -0,0 +1,14 @@ +withPhpSets(php83: true) + ->withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]); \ No newline at end of file diff --git a/src/DateTime.php b/src/DateTime.php index 24a0575..c3f536d 100644 --- a/src/DateTime.php +++ b/src/DateTime.php @@ -42,7 +42,7 @@ public static function now(): DateTimeInterface /** * @throws Exception */ - public static function fromString(string $time, DateTimeZone $timezone = null): static + public static function fromString(string $time, ?DateTimeZone $timezone = null): static { $dateTime = parent::createFromInterface(new \DateTime($time, $timezone)); \assert($dateTime instanceof static); @@ -53,7 +53,7 @@ public static function fromString(string $time, DateTimeZone $timezone = null): /** * @throws Exception */ - public static function fromTimestamp(int $timestamp, DateTimeZone $timezone = null): static + public static function fromTimestamp(int $timestamp, ?DateTimeZone $timezone = null): static { $dateTime = static::createFromFormat('U', (string) $timestamp); \assert(false !== $dateTime); @@ -63,7 +63,7 @@ public static function fromTimestamp(int $timestamp, DateTimeZone $timezone = nu : $dateTime->inDefaultTimezone(); } - public static function fromFloatTimestamp(float $timestamp, DateTimeZone $timezone = null): static + public static function fromFloatTimestamp(float $timestamp, ?DateTimeZone $timezone = null): static { $integer = floor($timestamp); $fract = fmod($timestamp, 1); @@ -80,21 +80,24 @@ public static function fromFloatTimestamp(float $timestamp, DateTimeZone $timezo } #[\ReturnTypeWillChange] + #[\Override] public static function createFromFormat( string $format, string $datetime, - DateTimeZone $timezone = null + ?DateTimeZone $timezone = null ): static|false { return parent::createFromFormat($format, $datetime, $timezone); } #[\ReturnTypeWillChange] + #[\Override] public static function createFromMutable(\DateTime $object): static { return parent::createFromMutable($object); } #[\ReturnTypeWillChange] + #[\Override] public static function createFromInterface(\DateTimeInterface $object): static { $dateTime = parent::createFromInterface($object); @@ -106,6 +109,7 @@ public static function createFromInterface(\DateTimeInterface $object): static /** * @throws Exception */ + #[\Override] public function diff(\DateTimeInterface $targetObject, bool $absolute = false): DateInterval { return DateInterval::fromDateInterval( @@ -113,56 +117,67 @@ public function diff(\DateTimeInterface $targetObject, bool $absolute = false): ); } + #[\Override] public function add(\DateInterval $interval): static { return parent::add($interval); } + #[\Override] public function sub(\DateInterval $interval): static { return parent::sub($interval); } + #[\Override] public function modify(string $modifier): static|false { return parent::modify($modifier); } + #[\Override] public function setDate(int $year, int $month, int $day): static { return parent::setDate($year, $month, $day); } + #[\Override] public function setISODate(int $year, int $week, int $dayOfWeek = 1): static { return parent::setISODate($year, $week, $dayOfWeek); } + #[\Override] public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): static { return parent::setTime($hour, $minute, $second, $microsecond); } + #[\Override] public function setTimestamp(int $timestamp): static { return parent::setTimestamp($timestamp); } + #[\Override] public function setTimezone(\DateTimeZone $timezone): static { return parent::setTimezone($timezone); } + #[\Override] public function equals(DateTimeInterface $dateTime): bool { return $this == $dateTime; } + #[\Override] public function inDefaultTimezone(): static { return $this->setTimezone(new DateTimeZone(date_default_timezone_get())); } + #[\Override] public function toString(): string { $format = static::$format @@ -175,11 +190,13 @@ public function toString(): string return $this->format($format); } + #[\Override] public function __toString(): string { return $this->toString(); } + #[\Override] public function jsonSerialize(): string { return $this->toString(); diff --git a/src/FrozenClock.php b/src/FrozenClock.php index 97ecfb0..234ca11 100644 --- a/src/FrozenClock.php +++ b/src/FrozenClock.php @@ -6,11 +6,8 @@ class FrozenClock implements ClockInterface { - private DateTime $now; - - public function __construct(DateTime $now = null) + public function __construct(private DateTime $now = new DateTime()) { - $this->now = $now ?? new DateTime(); } public function set(DateTime $now): void @@ -26,6 +23,7 @@ public function modify(string $modifier): void $this->now = $now; } + #[\Override] public function now(): DateTime { return $this->now; diff --git a/tests/src/DateTimeTest.php b/tests/src/DateTimeTest.php index d5fe41b..31d144f 100644 --- a/tests/src/DateTimeTest.php +++ b/tests/src/DateTimeTest.php @@ -189,10 +189,10 @@ public function testModify(): void public function testModifyFailed(): void { - $this->expectError(); - $this->expectErrorMessage('DateTimeImmutable::modify(): Failed to parse time string (foo) at position 0 (f): The timezone could not be found in the database'); + self::expectExceptionMessage('Failed to parse time string (foo) at position 0 (f): The timezone could not be found in the database'); $dateTime = DateTime::fromString('2016-05-12 22:37:46+02:00'); + $dateTime->modify('foo'); } diff --git a/tests/src/FrozenClockTest.php b/tests/src/FrozenClockTest.php index 1692c28..422f206 100644 --- a/tests/src/FrozenClockTest.php +++ b/tests/src/FrozenClockTest.php @@ -51,8 +51,7 @@ public function testItFailsToModify(): void { $clock = new FrozenClock(); - $this->expectError(); - $this->expectErrorMessage('DateTimeImmutable::modify(): Failed to parse time string (foo) at position 0 (f): The timezone could not be found in the database'); + self::expectExceptionMessage('DateTimeImmutable::modify(): Failed to parse time string (foo) at position 0 (f): The timezone could not be found in the database'); $clock->modify('foo'); }