Skip to content

Conversation

@dereuromark
Copy link
Member

Summary

This PR adds a ChronosInterval class that wraps DateInterval using the decorator pattern, as suggested by @markstory in #444.

Features

  • ISO 8601 Duration Formatting: __toString() returns proper ISO 8601 format (e.g., P1Y2M3DT4H5M6S)
  • Factory Methods:
    • create(string $spec) - Create from ISO 8601 spec
    • createFromValues(...) - Create from individual components
    • instance(DateInterval $interval) - Wrap an existing DateInterval
  • Native Interop: toNative() returns the underlying DateInterval for compatibility
  • Convenience Methods:
    • totalSeconds() - Approximate total seconds
    • totalDays() - Total days (exact if from diff())
    • isNegative() - Check if interval is inverted
    • isZero() - Check if interval has no duration
  • Property Access: Proxies y, m, d, h, i, s, f, invert, days

Example Usage

// Create from spec
$interval = ChronosInterval::create('P1Y2M3D');
echo $interval; // "P1Y2M3D"

// Create from values
$interval = ChronosInterval::createFromValues(hours: 2, minutes: 30);
echo $interval; // "PT2H30M"

// Wrap existing DateInterval
$diff = $date1->diff($date2);
$interval = ChronosInterval::instance($diff);

// Use with native code
someFunctionExpectingDateInterval($interval->toNative());

Discussion Points

This is a draft PR to gather feedback on the API design:

  1. Should we add arithmetic methods (add(), sub())?
  2. Should ChronosInterval be returned from Chronos::diff() instead of DateInterval?
  3. Any other methods that would be useful?

Related to #444

Test plan

  • Unit tests for all public methods
  • All existing tests pass (920 tests)
  • Code style passes

Implements a DateInterval wrapper using the decorator pattern as discussed.
This addresses the need for a proper interval class with:

- ISO 8601 duration string formatting via __toString()
- Factory methods: create(), createFromValues(), instance()
- toNative() for compatibility with code expecting DateInterval
- Convenience methods: totalSeconds(), totalDays(), isNegative(), isZero()
- Property access proxy to underlying DateInterval

Related to #444
Fixes PHPStan level 8 'Unsafe usage of new static()' errors.
@dereuromark dereuromark requested a review from markstory January 28, 2026 17:03
@dereuromark dereuromark changed the base branch from 3.x to 3.next January 28, 2026 17:05
@dereuromark dereuromark marked this pull request as ready for review January 28, 2026 17:05
@dereuromark dereuromark added this to the 3.next milestone Jan 28, 2026
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.

2 participants