Skip to content

Commit

Permalink
Skip mutation if immutable in setUnitNoOverflow
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed Oct 7, 2024
1 parent 29bbe89 commit 599606d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
22 changes: 19 additions & 3 deletions src/Carbon/Traits/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -1709,9 +1709,11 @@ public function setUnitNoOverflow(string $valueUnit, int $value, string $overflo
$end = $original->avoidMutation()->endOf($overflowUnit);

if ($date < $start) {
$date = $date->modify($start->rawFormat('Y-m-d H:i:s.u e O'));
} elseif ($date > $end) {
$date = $date->modify($end->rawFormat('Y-m-d H:i:s.u e O'));
return $date->mutateIfMutable($start);
}

if ($date > $end) {
return $date->mutateIfMutable($end);
}

return $date;
Expand Down Expand Up @@ -2953,4 +2955,18 @@ private static function floorZeroPad(int|float $value, int $length): string
{
return str_pad((string) floor($value), $length, '0', STR_PAD_LEFT);
}

/**
* @template T of CarbonInterface
*
* @param T $date
*
* @return T
*/
private function mutateIfMutable(CarbonInterface $date): CarbonInterface
{
return $this instanceof DateTimeImmutable
? $this
: $this->modify('@' . $date->rawFormat('U.u'))->setTimezone($date->getTimezone());
}
}
27 changes: 19 additions & 8 deletions tests/Carbon/SettersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

class SettersTest extends AbstractTestCase
{
public const SET_UNIT_NO_OVERFLOW_SAMPLE = 2_000;
public const SET_UNIT_NO_OVERFLOW_SAMPLE = 20_000;

public function testMonthEnum()
{
Expand Down Expand Up @@ -825,9 +825,9 @@ public function testAddUnitNoOverflow()
'valueUnit' => $valueUnit,
'value' => $value,
'overflowUnit' => $overflowUnit,
'date' => $date->format('Y-m-d H:i:s.u e'),
'start' => $start->format('Y-m-d H:i:s.u e'),
'end' => $end->format('Y-m-d H:i:s.u e'),
'date' => $date->format('Y-m-d H:i:s.u e O'),
'start' => $start->format('Y-m-d H:i:s.u e O'),
'end' => $end->format('Y-m-d H:i:s.u e O'),
];

continue;
Expand Down Expand Up @@ -934,9 +934,9 @@ public function testSubUnitNoOverflow()
'valueUnit' => $valueUnit,
'value' => $value,
'overflowUnit' => $overflowUnit,
'date' => $date->format('Y-m-d H:i:s.u e'),
'start' => $start->format('Y-m-d H:i:s.u e'),
'end' => $end->format('Y-m-d H:i:s.u e'),
'date' => $date->format('Y-m-d H:i:s.u e O'),
'start' => $start->format('Y-m-d H:i:s.u e O'),
'end' => $end->format('Y-m-d H:i:s.u e O'),
];

continue;
Expand Down Expand Up @@ -1009,6 +1009,17 @@ public function testSubUnitNoOverflow()
$this->assertSame(static::SET_UNIT_NO_OVERFLOW_SAMPLE, $results['end'] + $results['start'] + $results['current']);
}

public function testOverflowInDst()
{
$date = Carbon::create(2335, 11, 3, 1, 30, 50.138159);
$date->subUnitNoOverflow('year', 5668, 'second');

$this->assertSame(
'2335-11-03 01:30:50.000000 America/Toronto -0400',
$date->format('Y-m-d H:i:s.u e O'),
);
}

/**
* @SuppressWarnings(PHPMD.TooManyFields)
*/
Expand All @@ -1032,7 +1043,7 @@ private function failOperation(
")->$method(".implode(', ', array_map(function ($value) {
return var_export($value, true);
}, [$valueUnit, $value, $overflowUnit])).');',
'Getting: '.$date->format('Y-m-d H:i:s.u e'),
'Getting: '.$date->format('Y-m-d H:i:s.u e O'),
"Current $valueUnit: ".$date->$valueUnit,
'Is neither '.$start->$valueUnit." (from $start)",
'Nor '.$end->$valueUnit." (from $end)",
Expand Down

0 comments on commit 599606d

Please sign in to comment.