mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
DX: Add rolling date converter + unit test
This commit is contained in:
parent
5489178e4b
commit
c7f740d5d7
@ -77,7 +77,7 @@ class RollingDate
|
||||
* @param DateTimeImmutable|null $pivotDate Will be "now" if null is given
|
||||
* @param DateTimeImmutable|null $fixedDate Only to insert if $roll equals @see{self::T_FIXED_DATE}
|
||||
*/
|
||||
public function __construct(string $roll, ?DateTimeImmutable $pivotDate = null, ?DateTimeImmutable $fixedDate = null)
|
||||
public function __construct(string $roll, ?DateTimeImmutable $fixedDate = null, ?DateTimeImmutable $pivotDate = null)
|
||||
{
|
||||
$this->roll = $roll;
|
||||
$this->pivotDate = $pivotDate ?? new DateTimeImmutable('now');
|
||||
|
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Service\RollingDate;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeImmutable;
|
||||
use LogicException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class RollingDateConverter
|
||||
{
|
||||
public function convert(RollingDate $rollingDate): DateTimeImmutable
|
||||
{
|
||||
switch ($rollingDate->getRoll()) {
|
||||
case RollingDate::T_MONTH_CURRENT_START:
|
||||
return $this->toBeginOfMonth($rollingDate->getPivotDate());
|
||||
|
||||
case RollingDate::T_MONTH_NEXT_START:
|
||||
return $this->toBeginOfMonth($rollingDate->getPivotDate()->add(new DateInterval('P1M')));
|
||||
|
||||
case RollingDate::T_MONTH_PREVIOUS_START:
|
||||
return $this->toBeginOfMonth($rollingDate->getPivotDate()->sub(new DateInterval('P1M')));
|
||||
|
||||
case RollingDate::T_QUARTER_CURRENT_START:
|
||||
return $this->toBeginOfQuarter($rollingDate->getPivotDate());
|
||||
|
||||
case RollingDate::T_QUARTER_NEXT_START:
|
||||
return $this->toBeginOfQuarter($rollingDate->getPivotDate()->add(new DateInterval('P3M')));
|
||||
|
||||
case RollingDate::T_QUARTER_PREVIOUS_START:
|
||||
return $this->toBeginOfQuarter($rollingDate->getPivotDate()->sub(new DateInterval('P3M')));
|
||||
|
||||
case RollingDate::T_WEEK_CURRENT_START:
|
||||
return $this->toBeginOfWeek($rollingDate->getPivotDate());
|
||||
|
||||
case RollingDate::T_WEEK_NEXT_START:
|
||||
return $this->toBeginOfWeek($rollingDate->getPivotDate()->add(new DateInterval('P1W')));
|
||||
|
||||
case RollingDate::T_WEEK_PREVIOUS_START:
|
||||
return $this->toBeginOfWeek($rollingDate->getPivotDate()->sub(new DateInterval('P1W')));
|
||||
|
||||
case RollingDate::T_YEAR_CURRENT_START:
|
||||
return $this->toBeginOfYear($rollingDate->getPivotDate());
|
||||
|
||||
case RollingDate::T_YEAR_PREVIOUS_START:
|
||||
return $this->toBeginOfYear($rollingDate->getPivotDate()->sub(new DateInterval('P1Y')));
|
||||
|
||||
case RollingDate::T_YEAR_NEXT_START:
|
||||
return $this->toBeginOfYear($rollingDate->getPivotDate()->add(new DateInterval('P1Y')));
|
||||
|
||||
case RollingDate::T_TODAY:
|
||||
return $rollingDate->getPivotDate();
|
||||
|
||||
case RollingDate::T_FIXED_DATE:
|
||||
if (null === $rollingDate->getFixedDate()) {
|
||||
throw new \LogicException("You must provide a fixed date when selecting a fixed date");
|
||||
}
|
||||
return $rollingDate->getFixedDate();
|
||||
|
||||
default:
|
||||
throw new UnexpectedValueException(sprintf('%s rolling operation not supported', $rollingDate->getRoll()));
|
||||
}
|
||||
}
|
||||
|
||||
private function toBeginOfMonth(DateTimeImmutable $date): DateTimeImmutable
|
||||
{
|
||||
return DateTimeImmutable::createFromFormat(
|
||||
'Y-m-d His',
|
||||
sprintf('%s-%s-01 000000', $date->format('Y'), $date->format('m'))
|
||||
);
|
||||
}
|
||||
|
||||
private function toBeginOfQuarter(DateTimeImmutable $date): DateTimeImmutable
|
||||
{
|
||||
switch ((int) $date->format('n')) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
$month = '01';
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
$month = '04';
|
||||
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
$month = '07';
|
||||
|
||||
break;
|
||||
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
$month = '10';
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LogicException('this month is not valid: ' . $date->format('n'));
|
||||
}
|
||||
|
||||
return DateTimeImmutable::createFromFormat(
|
||||
'Y-m-d His',
|
||||
sprintf('%s-%s-01 000000', $date->format('Y'), $month)
|
||||
);
|
||||
}
|
||||
|
||||
private function toBeginOfWeek(DateTimeImmutable $date): DateTimeImmutable
|
||||
{
|
||||
if (1 === $dayOfWeek = (int) $date->format('N')) {
|
||||
return $date->setTime(0, 0, 0);
|
||||
}
|
||||
|
||||
return $date
|
||||
->sub(new DateInterval('P' . ($dayOfWeek - 1) . 'D'))
|
||||
->setTime(0, 0, 0);
|
||||
}
|
||||
|
||||
private function toBeginOfYear(DateTimeImmutable $date): DateTimeImmutable
|
||||
{
|
||||
return DateTimeImmutable::createFromFormat(
|
||||
'Y-m-d His',
|
||||
sprintf('%s-01-01 000000', $date->format('Y'))
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Services\RollingDate;
|
||||
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverter;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class RollingDateConverterTest extends TestCase
|
||||
{
|
||||
private RollingDateConverter $converter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->converter = new RollingDateConverter();
|
||||
}
|
||||
|
||||
public function generateDataConversionDate(): iterable
|
||||
{
|
||||
$format = 'Y-m-d His';
|
||||
|
||||
yield [RollingDate::T_MONTH_CURRENT_START, '2022-11-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_MONTH_NEXT_START, '2022-12-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_MONTH_PREVIOUS_START, '2022-10-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_QUARTER_CURRENT_START, '2022-10-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_QUARTER_NEXT_START, '2023-01-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_QUARTER_PREVIOUS_START, '2022-07-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_TODAY, '2022-11-07 000000', $format];
|
||||
|
||||
yield [RollingDate::T_WEEK_CURRENT_START, '2022-11-07 000000', $format];
|
||||
|
||||
yield [RollingDate::T_WEEK_NEXT_START, '2022-11-14 000000', $format];
|
||||
|
||||
yield [RollingDate::T_WEEK_PREVIOUS_START, '2022-10-31 000000', $format];
|
||||
|
||||
yield [RollingDate::T_YEAR_CURRENT_START, '2022-01-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_YEAR_NEXT_START, '2023-01-01 000000', $format];
|
||||
|
||||
yield [RollingDate::T_YEAR_PREVIOUS_START, '2021-01-01 000000', $format];
|
||||
}
|
||||
|
||||
public function testConversionFixedDate()
|
||||
{
|
||||
$rollingDate = new RollingDate(RollingDate::T_FIXED_DATE, new DateTimeImmutable('2022-01-01'));
|
||||
|
||||
$this->assertEquals(
|
||||
'2022-01-01',
|
||||
$this->converter->convert($rollingDate)->format('Y-m-d')
|
||||
);
|
||||
}
|
||||
|
||||
public function testConvertOnDateNow()
|
||||
{
|
||||
$rollingDate = new RollingDate(RollingDate::T_YEAR_PREVIOUS_START);
|
||||
|
||||
$actual = $this->converter->convert($rollingDate);
|
||||
|
||||
$this->assertEquals(
|
||||
(int) (new DateTimeImmutable('now'))->format('Y') - 1,
|
||||
(int) $actual->format('Y')
|
||||
);
|
||||
$this->assertEquals(1, (int) $actual->format('m'));
|
||||
$this->assertEquals(1, (int) $actual->format('d'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider generateDataConversionDate
|
||||
*/
|
||||
public function testConvertOnPivotDate(string $roll, string $expectedDateTime, string $format)
|
||||
{
|
||||
$pivot = DateTimeImmutable::createFromFormat('Y-m-d His', '2022-11-07 000000');
|
||||
$rollingDate = new RollingDate($roll, null, $pivot);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::createFromFormat($format, $expectedDateTime),
|
||||
$this->converter->convert($rollingDate)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user