From 9111182a59601784d259e4fcfc006768f90f2c13 Mon Sep 17 00:00:00 2001 From: BohdanK Date: Sat, 1 Mar 2025 12:41:14 +0200 Subject: [PATCH 1/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index ccb363d9e8821..a8d0cf4b6cc49 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -274,7 +274,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) $scopeTimeStamp = $this->scopeTimeStamp($scope); $fromTimeStamp = strtotime($dateFrom); $toTimeStamp = strtotime($dateTo); - if ($dateTo) { + if ($dateTo && date('H:i:s', strtotime($dateTo)) === '00:00:00') { // fix date YYYY-MM-DD 00:00:00 to YYYY-MM-DD 23:59:59 $toTimeStamp += 86400; } From 131815cfc58dff1d8569c7dc74369c19385a992f Mon Sep 17 00:00:00 2001 From: BohdanK Date: Wed, 2 Apr 2025 14:59:06 +0300 Subject: [PATCH 2/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice - changing Copyright --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index a8d0cf4b6cc49..5b9e0a5fe8410 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -1,7 +1,7 @@ Date: Thu, 10 Apr 2025 10:38:54 +0300 Subject: [PATCH 3/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice - added unit tests --- .../Test/Unit/DateTime/TimezoneTest.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 3b70f5d22b035..7ee2cdd473a41 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -426,6 +426,42 @@ public function testScopeDate($date, string $timezone, string $locale, string $e $this->assertEquals($timezone, $scopeDate->getTimezone()->getName()); } + /** + * @return void + * @throws \PHPUnit\Framework\MockObject\Exception + */ + public function testIsScopeDateInInterval() + { + $scopeMock = $this->createMock(\Magento\Framework\App\ScopeInterface::class); + $this->scopeResolver->method('getScope')->willReturn($scopeMock); + + $result = $this->getTimezone()->isScopeDateInInterval( + null, + '2025-04-01 00:00:00', + '2999-05-01 00:00:00', + ); + + $this->assertTrue($result); + } + + /** + * @return void + * @throws \PHPUnit\Framework\MockObject\Exception + */ + public function testIsScopeDateInIntervalFalse() + { + $scopeMock = $this->createMock(\Magento\Framework\App\ScopeInterface::class); + $this->scopeResolver->method('getScope')->willReturn($scopeMock); + + $result = $this->getTimezone()->isScopeDateInInterval( + null, + '2025-03-01 00:00:00', + '2025-04-01 00:00:00', + ); + + $this->assertFalse($result); + } + /** * @return array */ From e79e0fae9f970bd2ee5e29cac69c0286b64d96d8 Mon Sep 17 00:00:00 2001 From: KrasnoshchokBohdan Date: Mon, 14 Apr 2025 13:28:18 +0300 Subject: [PATCH 4/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice - fixes for static and unit test --- .../Test/Unit/DateTime/TimezoneScopeTest.php | 134 ++++++++++++++++++ .../Test/Unit/DateTime/TimezoneTest.php | 35 ----- 2 files changed, 134 insertions(+), 35 deletions(-) create mode 100644 lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php new file mode 100644 index 0000000000000..482f86fe6ade1 --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php @@ -0,0 +1,134 @@ +defaultTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $this->scopeType = 'store'; + $this->defaultTimezonePath = 'default/timezone/path'; + + $this->scopeResolver = $this->getMockBuilder(ScopeResolverInterface::class) + ->getMock(); + $this->localeResolver = $this->getMockBuilder(ResolverInterface::class) + ->getMock(); + $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class) + ->getMock(); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + date_default_timezone_set($this->defaultTimeZone); + } + + /** + * @return Timezone + * @throws Exception + */ + private function getTimezone(): Timezone + { + return new Timezone( + $this->scopeResolver, + $this->localeResolver, + $this->createMock(DateTime::class), + $this->scopeConfig, + $this->scopeType, + $this->defaultTimezonePath, + new DateFormatterFactory() + ); + } + + /** + * @return void + * @throws Exception + */ + public function testIsScopeDateInInterval() + { + $scopeMock = $this->createMock(ScopeInterface::class); + $this->scopeResolver->method('getScope')->willReturn($scopeMock); + + $result = $this->getTimezone()->isScopeDateInInterval( + null, + '2025-04-01 00:00:00', + '2999-05-01 00:00:00', + ); + + $this->assertTrue($result); + } + + /** + * @return void + * @throws Exception + */ + public function testIsScopeDateInIntervalFalse() + { + $scopeMock = $this->createMock(ScopeInterface::class); + $this->scopeResolver->method('getScope')->willReturn($scopeMock); + + $result = $this->getTimezone()->isScopeDateInInterval( + null, + '2025-03-01 00:00:00', + '2025-04-01 00:00:00', + ); + + $this->assertFalse($result); + } +} diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 7ee2cdd473a41..6f916e50a6461 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -426,41 +426,6 @@ public function testScopeDate($date, string $timezone, string $locale, string $e $this->assertEquals($timezone, $scopeDate->getTimezone()->getName()); } - /** - * @return void - * @throws \PHPUnit\Framework\MockObject\Exception - */ - public function testIsScopeDateInInterval() - { - $scopeMock = $this->createMock(\Magento\Framework\App\ScopeInterface::class); - $this->scopeResolver->method('getScope')->willReturn($scopeMock); - - $result = $this->getTimezone()->isScopeDateInInterval( - null, - '2025-04-01 00:00:00', - '2999-05-01 00:00:00', - ); - - $this->assertTrue($result); - } - - /** - * @return void - * @throws \PHPUnit\Framework\MockObject\Exception - */ - public function testIsScopeDateInIntervalFalse() - { - $scopeMock = $this->createMock(\Magento\Framework\App\ScopeInterface::class); - $this->scopeResolver->method('getScope')->willReturn($scopeMock); - - $result = $this->getTimezone()->isScopeDateInInterval( - null, - '2025-03-01 00:00:00', - '2025-04-01 00:00:00', - ); - - $this->assertFalse($result); - } /** * @return array From 0e95cd4afbee0328beb6f9a006493682bce45ac9 Mon Sep 17 00:00:00 2001 From: KrasnoshchokBohdan Date: Mon, 14 Apr 2025 13:29:46 +0300 Subject: [PATCH 5/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice - fix for static test --- .../Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 6f916e50a6461..3b70f5d22b035 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -426,7 +426,6 @@ public function testScopeDate($date, string $timezone, string $locale, string $e $this->assertEquals($timezone, $scopeDate->getTimezone()->getName()); } - /** * @return array */ From a3fe48cdc95363af7fe22052ef4536a15f3d6a44 Mon Sep 17 00:00:00 2001 From: KrasnoshchokBohdan Date: Tue, 15 Apr 2025 16:10:42 +0300 Subject: [PATCH 6/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 5b9e0a5fe8410..bf0e79b43906f 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -276,7 +276,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) $toTimeStamp = strtotime($dateTo); if ($dateTo && date('H:i:s', strtotime($dateTo)) === '00:00:00') { // fix date YYYY-MM-DD 00:00:00 to YYYY-MM-DD 23:59:59 - $toTimeStamp += 86400; + $toTimeStamp += 86399; } return !(!$this->_dateTime->isEmptyDate($dateFrom) && $scopeTimeStamp < $fromTimeStamp || From b42fab8c0a01d36a22aba33ec9b9876bff3cfba5 Mon Sep 17 00:00:00 2001 From: KrasnoshchokBohdan Date: Tue, 22 Apr 2025 16:46:42 +0300 Subject: [PATCH 7/7] magento/magento2#39169: Special Price To Date is wrongly validated on applySpecialPrice - more targeted solution to cover only the question described in the issue --- .../Catalog/Pricing/Price/SpecialPrice.php | 12 +- .../Framework/Stdlib/DateTime/Timezone.php | 4 +- .../Test/Unit/DateTime/TimezoneScopeTest.php | 134 ------------------ 3 files changed, 11 insertions(+), 139 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php diff --git a/app/code/Magento/Catalog/Pricing/Price/SpecialPrice.php b/app/code/Magento/Catalog/Pricing/Price/SpecialPrice.php index 77c48fdb1667e..6727ac23550ef 100644 --- a/app/code/Magento/Catalog/Pricing/Price/SpecialPrice.php +++ b/app/code/Magento/Catalog/Pricing/Price/SpecialPrice.php @@ -1,7 +1,7 @@ getSpecialToDate(); + if ($dateTo && date('H:i:s', strtotime($dateTo)) !== '00:00:00') { + $dateToTimestamp = strtotime($dateTo); + $dateTo = date('Y-m-d H:i:s', $dateToTimestamp - 86400); + } + return $this->localeDate->isScopeDateInInterval( WebsiteInterface::ADMIN_CODE, $this->getSpecialFromDate(), - $this->getSpecialToDate() + $dateTo ); } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index bf0e79b43906f..734dd10d61a52 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -274,9 +274,9 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) $scopeTimeStamp = $this->scopeTimeStamp($scope); $fromTimeStamp = strtotime($dateFrom); $toTimeStamp = strtotime($dateTo); - if ($dateTo && date('H:i:s', strtotime($dateTo)) === '00:00:00') { + if ($dateTo) { // fix date YYYY-MM-DD 00:00:00 to YYYY-MM-DD 23:59:59 - $toTimeStamp += 86399; + $toTimeStamp += 86400; } return !(!$this->_dateTime->isEmptyDate($dateFrom) && $scopeTimeStamp < $fromTimeStamp || diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php deleted file mode 100644 index 482f86fe6ade1..0000000000000 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneScopeTest.php +++ /dev/null @@ -1,134 +0,0 @@ -defaultTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $this->scopeType = 'store'; - $this->defaultTimezonePath = 'default/timezone/path'; - - $this->scopeResolver = $this->getMockBuilder(ScopeResolverInterface::class) - ->getMock(); - $this->localeResolver = $this->getMockBuilder(ResolverInterface::class) - ->getMock(); - $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class) - ->getMock(); - } - - /** - * @inheritdoc - */ - protected function tearDown(): void - { - date_default_timezone_set($this->defaultTimeZone); - } - - /** - * @return Timezone - * @throws Exception - */ - private function getTimezone(): Timezone - { - return new Timezone( - $this->scopeResolver, - $this->localeResolver, - $this->createMock(DateTime::class), - $this->scopeConfig, - $this->scopeType, - $this->defaultTimezonePath, - new DateFormatterFactory() - ); - } - - /** - * @return void - * @throws Exception - */ - public function testIsScopeDateInInterval() - { - $scopeMock = $this->createMock(ScopeInterface::class); - $this->scopeResolver->method('getScope')->willReturn($scopeMock); - - $result = $this->getTimezone()->isScopeDateInInterval( - null, - '2025-04-01 00:00:00', - '2999-05-01 00:00:00', - ); - - $this->assertTrue($result); - } - - /** - * @return void - * @throws Exception - */ - public function testIsScopeDateInIntervalFalse() - { - $scopeMock = $this->createMock(ScopeInterface::class); - $this->scopeResolver->method('getScope')->willReturn($scopeMock); - - $result = $this->getTimezone()->isScopeDateInInterval( - null, - '2025-03-01 00:00:00', - '2025-04-01 00:00:00', - ); - - $this->assertFalse($result); - } -}