Skip to content

Commit d2257ba

Browse files
authored
Merge pull request #30 from assoconnect/flo_feature_rm_month
Add removeMonth
2 parents e56d33e + a42b1e9 commit d2257ba

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

src/TimeTraveler.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace AssoConnect\PHPDate;
66

77
/**
8-
* This class addresses corner-case of the modify('+1 month') method
8+
* This class addresses corner-case of the ->modify('+/- 1 month') method
99
*/
1010
class TimeTraveler
1111
{
@@ -20,15 +20,32 @@ class TimeTraveler
2020
*/
2121
public function addMonth(AbsoluteDate $from): AbsoluteDate
2222
{
23-
$expectedMonth = (intval($from->format('n')) % 12) + 1;
23+
$currentMonth = intval($from->format('n'));
24+
$expectedMonth = $currentMonth + 1 === 13 ? 1 : $currentMonth + 1;
25+
2426
$next = $from->modify('+1 month');
27+
2528
while ($expectedMonth !== intval($next->format('n'))) {
2629
$next = $next->modify('-1 day');
2730
}
2831

2932
return $this->modifyForTheLastDayOfThisMonthIfNeedBe($next, $from);
3033
}
3134

35+
public function removeMonth(AbsoluteDate $from): AbsoluteDate
36+
{
37+
$currentMonth = intval($from->format('n'));
38+
$expectedMonth = $currentMonth - 1 === 0 ? 12 : $currentMonth - 1;
39+
40+
$previous = $from->modify('-1 month');
41+
42+
while ($expectedMonth !== intval($previous->format('n'))) {
43+
$previous = $previous->modify('-1 day');
44+
}
45+
46+
return $this->modifyForTheLastDayOfThisMonthIfNeedBe($previous, $from);
47+
}
48+
3249
/**
3350
* Ensures that months calculation are coherent year over year
3451
*

tests/TimeTravelerTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,38 @@ public function provideMonths(): iterable
3535
yield ['2020-06-30', '2020-07-31'];
3636
}
3737

38+
/** @dataProvider provideRemoveMonths */
39+
public function testRemoveMonth(string $from, string $expected): void
40+
{
41+
self::assertSame($expected, $this->timeTraveler->removeMonth(new AbsoluteDate($from))->__toString());
42+
}
43+
44+
/** @return iterable<string, array{string, string}> */
45+
public function provideRemoveMonths(): iterable
46+
{
47+
foreach (
48+
[
49+
'2020-01-01' => '2019-12-01',
50+
'2020-01-28' => '2019-12-28',
51+
'2020-01-29' => '2019-12-29',
52+
'2020-01-30' => '2019-12-30',
53+
'2020-01-31' => '2019-12-31',
54+
'2020-02-29' => '2020-01-31',
55+
'2020-06-30' => '2020-05-31',
56+
'2023-10-31' => '2023-09-30',
57+
'2023-08-31' => '2023-07-31',
58+
'2023-09-30' => '2023-08-31',
59+
'2023-03-31' => '2023-02-28',
60+
'2024-03-31' => '2024-02-29',
61+
] as $currentMonth => $expectedPreviousMonth
62+
) {
63+
yield sprintf('%s: previous month will %s', $currentMonth, $expectedPreviousMonth) => [
64+
$currentMonth,
65+
$expectedPreviousMonth,
66+
];
67+
}
68+
}
69+
3870
/** @dataProvider provideMonthsWithReference */
3971
public function testAddMonthWithReference(string $reference, string $from, string $expected): void
4072
{

0 commit comments

Comments
 (0)