Skip to content

Commit

Permalink
Fix strange behavior of PHP easter_date function
Browse files Browse the repository at this point in the history
  • Loading branch information
natitech committed Jul 6, 2023
1 parent e3e53c3 commit f2f3ecc
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
25 changes: 9 additions & 16 deletions src/ChristianCalendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

final class ChristianCalendar
{
private const MAX_PHP_EASTER_YEAR = 2037;

public function getEasterFriday(int $year): \DateTimeImmutable
{
return $this->getDateAroundEaster($year, -2);
Expand All @@ -28,28 +26,23 @@ public function getAscensionDay(int $year): \DateTimeImmutable

private function getDateAroundEaster(int $year, int $nbDaysAfterEaster): \DateTimeImmutable
{
$easter = $this->getEasterDate($year);

if ($nbDaysAfterEaster === 0) {
return $easter;
}

$interval = new \DateInterval('P' . abs($nbDaysAfterEaster) . 'D');

return $nbDaysAfterEaster > 0 ? $easter->add($interval) : $easter->sub($interval);
return $this->addDays($this->getEasterDate($year), $nbDaysAfterEaster);
}

/** @see <https://www.php.net/manual/en/function.easter-date.php#refsect1-function.easter-date-notes> */
private function getEasterDate(int $year): \DateTimeImmutable
{
return \DateTimeImmutable::createFromFormat('U', easter_date($this->guardEasterYear($year)));
return $this->addDays(new \DateTimeImmutable($year . '-03-21'), easter_days($year));
}

private function guardEasterYear(int $year): int
private function addDays(\DateTimeImmutable $date, int $nbDays): \DateTimeImmutable
{
if ($year > self::MAX_PHP_EASTER_YEAR) {
throw new \InvalidArgumentException('Easter date not found');
if ($nbDays === 0) {
return $date;
}

return $year;
$interval = new \DateInterval('P' . abs($nbDays) . 'D');

return $nbDays > 0 ? $date->add($interval) : $date->sub($interval);
}
}
10 changes: 0 additions & 10 deletions test/Integration/StaticFRBusinessCalendarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@

class StaticFRBusinessCalendarTest extends FRBusinessCalendarTest
{
/**
* @test
*/
public function whenYearIsBeyondPHPThenThrowException()
{
$this->expectException(\InvalidArgumentException::class);

$this->add('2036/01/01', 720);
}

/**
* @test
*/
Expand Down
33 changes: 33 additions & 0 deletions test/Unit/ChristianCalendarTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Nati\Businesscal\Test\Unit;

use Nati\Businesscal\ChristianCalendar;
use PHPUnit\Framework\TestCase;

final class ChristianCalendarTest extends TestCase
{
/**
* @test
*/
public function canReturnEasterDateBasedHolidayWhateverTZ()
{
//The purpose of this test is to fix strange behavior of easter_date PHP function

putenv('TZ=UTC');
$this->assertEquals('18/05', (new ChristianCalendar())->getAscensionDay(2023)->format('d/m'));

putenv('TZ=Europe/Paris');
$this->assertEquals('18/05', (new ChristianCalendar())->getAscensionDay(2023)->format('d/m'));
}

/**
* @test
*/
public function canReturnEasterDateBasedHolidayEvenInDistantFuture()
{
//The purpose of this test is to fix strange behavior of easter_date PHP function

$this->assertEquals('18/05', (new ChristianCalendar())->getAscensionDay(2045)->format('d/m'));
}
}

0 comments on commit f2f3ecc

Please sign in to comment.