Skip to content

Return ChronosInterval from Chronos::diff()#515

Merged
dereuromark merged 6 commits into
4.xfrom
diff-returns-interval
May 24, 2026
Merged

Return ChronosInterval from Chronos::diff()#515
dereuromark merged 6 commits into
4.xfrom
diff-returns-interval

Conversation

@dereuromark
Copy link
Copy Markdown
Member

@dereuromark dereuromark commented Mar 26, 2026

Summary

  • Changes Chronos::diff() and ChronosDate::diff() to return ChronosInterval instead of DateInterval
  • Adds the ChronosInterval class (merged from 3.x branch)
  • Updates fromNow() to return ChronosInterval

This provides:

  • ISO 8601 duration formatting via __toString()
  • Convenience methods like totalSeconds(), totalDays(), isZero(), isNegative()
  • Arithmetic methods add(), sub()
  • toDateString() for strtotime-compatible output
  • toNative() for backwards compatibility when a DateInterval is needed

Migration Path

Users who need a DateInterval can call ->toNative() on the result:

// Before (3.x)
$interval = $date1->diff($date2);

// After (4.x) - if DateInterval is needed
$interval = $date1->diff($date2)->toNative();

// After (4.x) - using new features
$interval = $date1->diff($date2);
echo $interval; // "P1Y2M3D"
echo $interval->totalDays();

Note

Good news: No changes required in CakePHP core!

PHPStan reports an error about covariant return types - this is expected for this BC break. The baseline will need to be updated.

Closes #511

@dereuromark
Copy link
Copy Markdown
Member Author

dereuromark commented Mar 26, 2026

For downstream users:

Anyone using $chronos->diff() with type hints will need updates:

// If they have:                                                                                                   
function process(DateInterval $interval) { ... }                                                                   
                                                                                                                     
// They need:                                                                                                      
function process(DateInterval|ChronosInterval $interval) { ... }                                                   
// Or:                                                                                                             
$date->diff($other)->toNative()  // to get DateInterval                                                            

CI Status

All 954 tests pass. The CI failures are due to:

  1. PHPStan - Expected error about covariant return type:

    Return type ChronosInterval of method Chronos::diff() is not covariant with tentative return type DateInterval of method DateTimeInterface::diff()

  2. PHPUnit (PHP 8.3+) - The repo has failOnDeprecation="true" in phpunit.xml.dist, so the PHP deprecation notice about incompatible return types causes tests to fail even though they all pass.

Both issues are expected for this BC break. We will need to decide how to handle:

  • Update phpstan.neon to ignore this specific error
  • Either update phpunit.xml.dist or add baseline for the deprecation

This changes Chronos::diff() and ChronosDate::diff() to return
ChronosInterval instead of DateInterval. This provides:

- ISO 8601 duration formatting via __toString()
- Convenience methods like totalSeconds(), totalDays(), isZero(), isNegative()
- Arithmetic methods add(), sub()
- toDateString() for strtotime-compatible output
- toNative() for backwards compatibility when DateInterval is needed

Users who need a DateInterval can call ->toNative() on the result.

Also updates fromNow() to return ChronosInterval.

Closes #511
Suppress PHP deprecation notice and PHPStan errors for the
intentional return type change from DateInterval to ChronosInterval.
@dereuromark dereuromark force-pushed the diff-returns-interval branch from 15c25e2 to 556c707 Compare March 26, 2026 14:04
@dereuromark dereuromark marked this pull request as ready for review March 26, 2026 14:12
@dereuromark dereuromark added this to the 4.x milestone Mar 29, 2026
@dereuromark dereuromark requested a review from markstory April 2, 2026 13:05
@LordSimal
Copy link
Copy Markdown
Contributor

Docs are missing, other than that, it looks good.

@dereuromark dereuromark requested a review from ADmad May 3, 2026 12:20
@dereuromark
Copy link
Copy Markdown
Member Author

Done.

Copy link
Copy Markdown

@jamisonbryant jamisonbryant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Docs look good too. Should we add a “since” admonition like the book does or is the migration guide sufficient?

@dereuromark dereuromark merged commit e3ac64b into 4.x May 24, 2026
8 checks passed
@dereuromark dereuromark deleted the diff-returns-interval branch May 24, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants