From 138b379e9113dd712b54f8b69e46b908181cb538 Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 11:31:13 +0200 Subject: [PATCH 1/6] Add native modify --- src/Aeon/Calendar/Gregorian/DateTime.php | 9 +++++++++ .../Calendar/Tests/Unit/Gregorian/DateTimeTest.php | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index 1148372a..d3ab3e11 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -369,6 +369,15 @@ public function modify(string $modifier) : self ); } + public function nativeModify(string $modifier) : self + { + return self::fromDateTime( + $this + ->toDateTimeImmutable() + ->modify($modifier) + ); + } + public function addHour() : self { return $this->add(TimeUnit::hour()); diff --git a/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php b/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php index 7d7eb168..02e7e932 100644 --- a/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php +++ b/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php @@ -421,6 +421,20 @@ public function modify_datetime() : \Generator yield ['2022-10-25 15:00:00 UTC', 'previous Saturday', '2022-10-22 15:00:00 UTC']; } + // It switches back 14 days in a timezone aware manner + public function test_native_modify() : void + { + $nativeBaseDate = new \DateTimeImmutable( + '2023-04-01 00:00:00', + new \DateTimeZone('Europe/Berlin'), + ); + $expectedDate = DateTime::fromDateTime($nativeBaseDate->modify('- 14 days')); + + $modifiedDate = DateTime::fromDateTime($nativeBaseDate)->nativeModify('- 14 days'); + + $this->assertTrue($modifiedDate->isEqualTo($expectedDate)); + } + public function test_time() : void { $dateTime = DateTime::fromString('2020-01-01 12:54:23.001000'); From 1000cafb7e7fd5bcff5084f3b5c1c645a6228636 Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 12:12:20 +0200 Subject: [PATCH 2/6] Validate against false --- src/Aeon/Calendar/Gregorian/DateTime.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index d3ab3e11..58868b97 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -371,11 +371,14 @@ public function modify(string $modifier) : self public function nativeModify(string $modifier) : self { - return self::fromDateTime( - $this + $modifiedDateTime = $this ->toDateTimeImmutable() - ->modify($modifier) - ); + ->modify($modifier); + if ($modifiedDateTime === false) { + throw new \InvalidArgumentException("The modifier \"{$modifier}\" is not valid."); + } + + return self::fromDateTime($modifiedDateTime); } public function addHour() : self From 64818d7fa4c8b79d102d9b2504f0733daac9cccd Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 12:22:57 +0200 Subject: [PATCH 3/6] Add cs fixes --- src/Aeon/Calendar/Gregorian/DateTime.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index 58868b97..8655a382 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -374,6 +374,7 @@ public function nativeModify(string $modifier) : self $modifiedDateTime = $this ->toDateTimeImmutable() ->modify($modifier); + if ($modifiedDateTime === false) { throw new \InvalidArgumentException("The modifier \"{$modifier}\" is not valid."); } From e1dfcff8f058b0453c9408783b66e3b6c1ae539e Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 14:40:45 +0200 Subject: [PATCH 4/6] Validate modification with date parts --- src/Aeon/Calendar/Gregorian/DateTime.php | 13 +++++++++---- .../Calendar/Tests/Unit/Gregorian/DateTimeTest.php | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index 8655a382..f38ed35f 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -371,14 +371,19 @@ public function modify(string $modifier) : self public function nativeModify(string $modifier) : self { - $modifiedDateTime = $this - ->toDateTimeImmutable() - ->modify($modifier); + $dateTimeParts = \date_parse($modifier); - if ($modifiedDateTime === false) { + if ($dateTimeParts === false + || $dateTimeParts['error_count'] > 0 + ) { throw new \InvalidArgumentException("The modifier \"{$modifier}\" is not valid."); } + /** @var \DateTimeImmutable $modifiedDateTime */ + $modifiedDateTime = $this + ->toDateTimeImmutable() + ->modify($modifier); + return self::fromDateTime($modifiedDateTime); } diff --git a/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php b/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php index 02e7e932..7375fddf 100644 --- a/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php +++ b/tests/Aeon/Calendar/Tests/Unit/Gregorian/DateTimeTest.php @@ -435,6 +435,14 @@ public function test_native_modify() : void $this->assertTrue($modifiedDate->isEqualTo($expectedDate)); } + public function test_native_modify_with_invalid_modifier() : void + { + $this->expectException(\InvalidArgumentException::class); + + DateTime::fromString('2022-09-28 00:00:00') + ->nativeModify('invalid modifier'); + } + public function test_time() : void { $dateTime = DateTime::fromString('2020-01-01 12:54:23.001000'); From de1adf6687f31677191960d79ac17308c0f372ad Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 14:54:02 +0200 Subject: [PATCH 5/6] Add annotation for PHP 7.4 --- src/Aeon/Calendar/Gregorian/DateTime.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index f38ed35f..6aa33780 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -371,6 +371,7 @@ public function modify(string $modifier) : self public function nativeModify(string $modifier) : self { + /** @var array|false $dateTimeParts */ $dateTimeParts = \date_parse($modifier); if ($dateTimeParts === false From 4a85d3f2b698a2a328b7aec620d54c977621a5f8 Mon Sep 17 00:00:00 2001 From: Christian Kolb Date: Wed, 28 Sep 2022 14:57:54 +0200 Subject: [PATCH 6/6] Remove annotation again --- src/Aeon/Calendar/Gregorian/DateTime.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Aeon/Calendar/Gregorian/DateTime.php b/src/Aeon/Calendar/Gregorian/DateTime.php index 6aa33780..f38ed35f 100644 --- a/src/Aeon/Calendar/Gregorian/DateTime.php +++ b/src/Aeon/Calendar/Gregorian/DateTime.php @@ -371,7 +371,6 @@ public function modify(string $modifier) : self public function nativeModify(string $modifier) : self { - /** @var array|false $dateTimeParts */ $dateTimeParts = \date_parse($modifier); if ($dateTimeParts === false