Skip to content

Commit

Permalink
Merge pull request #3098 from briannesbitt/fix/issue-3096-float-secon…
Browse files Browse the repository at this point in the history
…d-interval

Parse microseconds as integer when making from specs
  • Loading branch information
kylekatarnls authored Nov 3, 2024
2 parents cb0fd28 + a8fefff commit 10ac0aa
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/Carbon/CarbonInterval.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,11 @@ public function __construct($years = null, $months = null, $weeks = null, $days
$this->assertSafeForInteger('minute', $minutes);
$seconds = (float) ($match['second'] ?? 0);
$this->assertSafeForInteger('second', $seconds);
$microseconds = (int) str_pad(
substr(explode('.', $match['second'] ?? '0.0')[1] ?? '0', 0, 6),
6,
'0',
);
}

$totalDays = (($weeks * static::getDaysPerWeek()) + $days);
Expand All @@ -508,22 +513,28 @@ public function __construct($years = null, $months = null, $weeks = null, $days
$this->h = (int) $hours;
$this->i = (int) $minutes;
$this->s = (int) $seconds;
$secondFloatPart = (float) ($microseconds / CarbonInterface::MICROSECONDS_PER_SECOND);
$this->f = $secondFloatPart;
$intervalMicroseconds = (int) ($this->f * CarbonInterface::MICROSECONDS_PER_SECOND);
$intervalSeconds = $seconds - $secondFloatPart;

if (
((float) $this->y) !== $years ||
((float) $this->m) !== $months ||
((float) $this->d) !== $totalDays ||
((float) $this->h) !== $hours ||
((float) $this->i) !== $minutes ||
((float) $this->s) !== $seconds
((float) $this->s) !== $intervalSeconds ||
$intervalMicroseconds !== ((int) $microseconds)
) {
$this->add(static::fromString(
($years - $this->y).' years '.
($months - $this->m).' months '.
($totalDays - $this->d).' days '.
($hours - $this->h).' hours '.
($minutes - $this->i).' minutes '.
($seconds - $this->s).' seconds '
($intervalSeconds - $this->s).' seconds '.
($microseconds - $intervalMicroseconds).' microseconds ',
));
}
} catch (Throwable $secondException) {
Expand All @@ -532,7 +543,7 @@ public function __construct($years = null, $months = null, $weeks = null, $days
}

if ($microseconds !== null) {
$this->f = $microseconds / Carbon::MICROSECONDS_PER_SECOND;
$this->f = $microseconds / CarbonInterface::MICROSECONDS_PER_SECOND;
}

foreach (['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'] as $unit) {
Expand Down
3 changes: 3 additions & 0 deletions tests/CarbonInterval/ConstructTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ public function testMake()
$this->assertCarbonInterval(CarbonInterval::make(3, 'hours'), 0, 0, 0, 3, 0, 0);
$this->assertCarbonInterval(CarbonInterval::make('3 hours 30 m'), 0, 0, 0, 3, 30, 0);
$this->assertCarbonInterval(CarbonInterval::make('PT5H'), 0, 0, 0, 5, 0, 0);
$this->assertCarbonInterval(CarbonInterval::make('PT13.516837S'), 0, 0, 0, 0, 0, 13, 516_837);
$this->assertCarbonInterval(CarbonInterval::make('PT13.000001S'), 0, 0, 0, 0, 0, 13, 1);
$this->assertCarbonInterval(CarbonInterval::make('PT13.001S'), 0, 0, 0, 0, 0, 13, 1_000);
$this->assertCarbonInterval(CarbonInterval::make(new DateInterval('P1D')), 0, 0, 1, 0, 0, 0);
$this->assertCarbonInterval(CarbonInterval::make(new CarbonInterval('P2M')), 0, 2, 0, 0, 0, 0);
$this->assertNull(CarbonInterval::make(3));
Expand Down

0 comments on commit 10ac0aa

Please sign in to comment.