Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions system/I18n/TimeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,9 @@ public function toDateTime()
* @param DateTimeInterface|self|string|null $datetime
* @param DateTimeZone|string|null $timezone
*
* @return void
*
* @throws Exception
*/
public static function setTestNow($datetime = null, $timezone = null, ?string $locale = null)
public static function setTestNow($datetime = null, $timezone = null, ?string $locale = null): void
{
// Reset the test instance
if ($datetime === null) {
Expand Down Expand Up @@ -749,6 +747,39 @@ public function addMonths(int $months)
return $time->add(DateInterval::createFromDateString("{$months} months"));
}

/**
* Returns a new Time instance with $months calendar months added to the time.
*/
public function addCalendarMonths(int $months): static
{
$time = clone $this;

$year = (int) $time->getYear();
$month = (int) $time->getMonth();
$day = (int) $time->getDay();

// Adjust total months since year 0
$totalMonths = ($year * 12 + $month - 1) + $months;

// Recalculate year and month
$newYear = intdiv($totalMonths, 12);
$newMonth = $totalMonths % 12 + 1;

// Get last day of new month
$lastDayOfMonth = cal_days_in_month(CAL_GREGORIAN, $newMonth, $newYear);
$correctedDay = min($day, $lastDayOfMonth);

return static::create($newYear, $newMonth, $correctedDay, (int) $this->getHour(), (int) $this->getMinute(), (int) $this->getSecond(), $this->getTimezone(), $this->locale);
}

/**
* Returns a new Time instance with $months calendar months subtracted from the time
*/
public function subCalendarMonths(int $months): static
{
return $this->addCalendarMonths(-$months);
}

/**
* Returns a new Time instance with $years added to the time.
*
Expand Down
32 changes: 32 additions & 0 deletions tests/system/I18n/TimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,22 @@ public function testCanAddMonthsOverYearBoundary(): void
$this->assertSame('2018-02-10 13:20:33', $newTime->toDateTimeString());
}

public function testCanAddCalendarMonths(): void
{
$time = Time::parse('January 31, 2017 13:20:33', 'America/Chicago');
$newTime = $time->addCalendarMonths(1);
$this->assertSame('2017-01-31 13:20:33', $time->toDateTimeString());
$this->assertSame('2017-02-28 13:20:33', $newTime->toDateTimeString());
}

public function testCanAddCalendarMonthsOverYearBoundary(): void
{
$time = Time::parse('January 31, 2017 13:20:33', 'America/Chicago');
$newTime = $time->addCalendarMonths(13);
$this->assertSame('2017-01-31 13:20:33', $time->toDateTimeString());
$this->assertSame('2018-02-28 13:20:33', $newTime->toDateTimeString());
}

public function testCanAddYears(): void
{
$time = Time::parse('January 10, 2017 13:20:33', 'America/Chicago');
Expand Down Expand Up @@ -860,6 +876,22 @@ public function testCanSubtractMonths(): void
$this->assertSame('2016-10-10 13:20:33', $newTime->toDateTimeString());
}

public function testCanSubtractCalendarMonths(): void
{
$time = Time::parse('March 31, 2017 13:20:33', 'America/Chicago');
$newTime = $time->subCalendarMonths(1);
$this->assertSame('2017-03-31 13:20:33', $time->toDateTimeString());
$this->assertSame('2017-02-28 13:20:33', $newTime->toDateTimeString());
}

public function testCanSubtractCalendarMonthsOverYearBoundary(): void
{
$time = Time::parse('March 31, 2017 13:20:33', 'America/Chicago');
$newTime = $time->subCalendarMonths(13);
$this->assertSame('2017-03-31 13:20:33', $time->toDateTimeString());
$this->assertSame('2016-02-29 13:20:33', $newTime->toDateTimeString());
}

public function testCanSubtractYears(): void
{
$time = Time::parse('January 10, 2017 13:20:33', 'America/Chicago');
Expand Down
5 changes: 5 additions & 0 deletions user_guide_src/source/changelogs/v4.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ Method Signature Changes
Enhancements
************

Libraries
=========

- **Time:** added functions ``Time::addCalendarMonths()`` and ``Time::subCalendarMonths()``

Commands
========

Expand Down
2 changes: 2 additions & 0 deletions user_guide_src/source/libraries/time/031.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
$time = $time->addHours(12);
$time = $time->addDays(21);
$time = $time->addMonths(14);
$time = $time->addCalendarMonths(2);
$time = $time->addYears(5);

$time = $time->subSeconds(23);
$time = $time->subMinutes(15);
$time = $time->subHours(12);
$time = $time->subDays(21);
$time = $time->subMonths(14);
$time = $time->subCalendarMonths(2);
$time = $time->subYears(5);
Loading