phpnomad / chronos-integration
Chronos-backed implementation of the phpnomad/chrono catalog. One concrete class fulfilling every non-platform chrono interface against cakephp/chronos.
Requires
- php: >=8.2
- ext-intl: *
- cakephp/chronos: ^2.4 || ^3.0
- phpnomad/chrono: ^1.0
- phpnomad/loader: ^1.0 || ^2.0
Requires (Dev)
- phpunit/phpunit: ^10.0
README
Chronos-backed implementation of the phpnomad/chrono catalog. Ships one concrete class, ChronosChronoStrategy, that fulfills every non-platform chrono interface against cakephp/chronos — with IntlDateFormatter providing the locale-aware formatting that Chronos 3.x dropped.
The default comprehensive integration for chrono. About a fifth the install footprint of nesbot/carbon with effectively the same surface, plus locale support through ext-intl instead of bundled translation files.
Requirements
PHP 8.2 or newer, ext-intl, phpnomad/chrono ^1.0, cakephp/chronos ^2.4 || ^3.0.
Installation
composer require phpnomad/chronos-integration
The package's Initializer registers ChronosChronoStrategy against the chrono catalog. Apps using PHPNomad's loader pick this up automatically.
What gets bound
A single ChronosChronoStrategy instance fulfills these 28 chrono interfaces:
ClockStrategyCanCheckIfPast,CanCheckIfFuture,CanCheckIfWeekend,CanCheckIfWeekdayCanCheckSameDay,CanCheckSameMonth,CanCheckSameYear,CanCheckBetweenCanApplyModifier,CanAddInterval,CanSubtractIntervalCanGetStartOfDay,CanGetEndOfDay,CanGetStartOfMonth,CanGetEndOfMonth,CanGetStartOfYear,CanGetEndOfYearCanGetDifference,CanGetDifferenceInDays,CanGetDifferenceInHours,CanGetDifferenceInMinutes,CanGetDifferenceInSecondsCanParseDate,CanParseDateWithFormatCanFormatDate,CanFormatLocalizedDate,CanFormatRelativeTime
What does NOT get bound here
HasTimezone and HasLocale are intentionally not implemented by this integration. Chronos does not own the platform's timezone or locale; those come from the host environment.
The ChronosChronoStrategy constructor declares both as dependencies:
public function __construct( HasTimezone $timezone, HasLocale $locale, )
Pair with phpnomad/wordpress-integration (which resolves both from WordPress site settings) or supply your own concretes. 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
- Format string syntax differs across methods.
format()takes PHP's nativedate()syntax.formatLocalized()takes ICU pattern syntax viaIntlDateFormatter— see the ICU patterns reference for the grammar. relative()is English-only. Chronos 3.x ships a deliberately English-onlydiffForHumanstranslator, so the injected locale is ignored by this method. Apps needing locale-aware relative-time strings should pair withphpnomad/wordpress-integration(which uses WordPress's translation pipeline againsthuman_time_diff()) orphpnomad/carbon-integration(Carbon ships 281 locales).isBetweenis inclusive on both bounds, matching Chronos'sbetween(true)default.apply()uses nativeDateTimeImmutable::modify(), so PHP's default month-overflow behavior applies. PreferCanAddIntervalwith explicit intervals for safer math.parseFormat()throwsInvalidArgumentExceptionwhen the input cannot be parsed against the supplied format.diffIn*methods are signed.diffInDays($a, $b)returns positive when$bis after$aand negative otherwise.- Chronos's
setTestNow()is honored bynow()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 Chronos::now(), Chronos's built-in test helper works without any chrono-specific machinery:
use Cake\Chronos\Chronos; Chronos::setTestNow('2026-05-27 12:00:00'); // ... exercise code that uses ChronosChronoStrategy Chronos::setTestNow(); // clear
For PSR-20-style fixed clocks, bind any PSR-20 implementation directly to ClockStrategy in your DI container — it will replace just the clock binding while leaving the rest of the Chronos-backed cluster intact.
Why Chronos and not Carbon
Chronos is a CakePHP-maintained immutable datetime library that started as a fork of early Carbon and has stayed disciplined about scope. The trade-offs:
- Roughly five times lighter than Carbon by file count and dependency footprint
- No bundled translation files — uses
ext-intl(bundled with most PHP distributions) for locale-aware formatting - Same API shape as Carbon for the methods chrono uses — drop-in equivalent
- English-only
diffForHumansis the one real concession; pair with a locale-aware integration if needed
If you already have Carbon in your stack (Laravel apps especially), use phpnomad/carbon-integration — there's no marginal cost since Carbon is already loaded.