Skip to content

phpnomad/carbon-integration

Repository files navigation

PHPNomad Carbon Integration

Carbon-backed implementation of the phpnomad/chrono catalog. Ships one concrete class, CarbonChronoStrategy, that fulfills every chrono interface Carbon can natively cover.

Requirements

PHP 8.2 or newer, phpnomad/chrono ^1.0, nesbot/carbon ^2.72 || ^3.0.

Installation

composer require phpnomad/carbon-integration

The package's Initializer registers CarbonChronoStrategy against the chrono catalog. Apps using PHPNomad's loader pick this up automatically.

What gets bound

A single CarbonChronoStrategy instance fulfills these 28 chrono interfaces:

  • ClockStrategy
  • CanCheckIfPast, CanCheckIfFuture, CanCheckIfWeekend, CanCheckIfWeekday
  • CanCheckSameDay, CanCheckSameMonth, CanCheckSameYear, CanCheckBetween
  • CanApplyModifier, CanAddInterval, CanSubtractInterval
  • CanGetStartOfDay, CanGetEndOfDay, CanGetStartOfMonth, CanGetEndOfMonth, CanGetStartOfYear, CanGetEndOfYear
  • CanGetDifference, CanGetDifferenceInDays, CanGetDifferenceInHours, CanGetDifferenceInMinutes, CanGetDifferenceInSeconds
  • CanParseDate, CanParseDateWithFormat
  • CanFormatDate, CanFormatLocalizedDate, CanFormatRelativeTime

What does NOT get bound here

HasTimezone and HasLocale are intentionally not implemented by this integration. Carbon does not own the platform's timezone or locale; those come from the host environment.

The CarbonChronoStrategy constructor declares both as dependencies:

public function __construct(
    HasTimezone $timezone,
    HasLocale   $locale,
)

Pair this integration with one that provides those interfaces — for example phpnomad/wordpress-integration, which resolves them from WordPress site settings. Without a HasTimezone and HasLocale binding in the container, the strategy cannot be instantiated.

Model-side chrono interfaces (HasCreatedDate, HasModifiedDate) are likewise not implemented here — they are contracts for domain models, not platform capabilities.

Behavior notes

A few decisions worth knowing about:

  • isBetween is inclusive on both bounds, matching Carbon's between(true) default.
  • apply() uses native DateTimeImmutable::modify(), so month overflow follows PHP's default behavior (Jan 31 + "1 month" is March 3). For month-end-safe arithmetic, prefer CanAddInterval with an explicit DateInterval or use Carbon's addMonthsNoOverflow directly.
  • parseFormat() throws InvalidArgumentException when the input cannot be parsed against the supplied format.
  • diffIn* methods are signed. diffInDays($a, $b) returns positive when $b is after $a and negative otherwise. Fractional results from Carbon 3 are truncated to integers.
  • Carbon's static setTestNow() is honored by now() and therefore by every predicate that consults it, which makes the whole strategy deterministic in tests.

Testing in your own app

Because now() delegates to CarbonImmutable::now(), Carbon's standard test helper works without any chrono-specific machinery:

use Carbon\CarbonImmutable;

CarbonImmutable::setTestNow('2026-05-27 12:00:00');
// ... exercise code that uses CarbonChronoStrategy
CarbonImmutable::setTestNow(); // clear

For PSR-20-style fixed clocks, bind Lcobucci\Clock\FrozenClock (or any PSR-20 implementation) to ClockStrategy in your DI container instead — it will replace just the clock binding while leaving the rest of the Carbon-backed cluster intact.

License

MIT

About

Carbon-backed implementation of the phpnomad/chrono catalog. One concrete class fulfilling every non-model chrono interface against nesbot/carbon.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages