Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Chronos Laravel Package

cakephp/chronos

Chronos is an immutable date and datetime library for PHP. It offers Chronos and ChronosDate objects that prevent accidental modification, keeping data predictable, and adds handy conveniences beyond native DateTime. Install via Composer with cakephp/chronos.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Chronos is a framework-agnostic value-object library, so it slots into a Laravel codebase as a domain-layer dependency rather than an infrastructure one. The 3.x design is the interesting part for a TPM: Chronos no longer extends DateTimeImmutable and no longer implements DateTimeInterface; it is a wrapper with ChronosDate (date-only, time frozen at 00:00:00) and ChronosTime (time-only) as distinct types. That is a deliberate trade: it gives you clean domain modeling — no accidental mixing of a calendar date with an instant — and it costs you drop-in interop with every API that type-hints DateTimeInterface. For a Laravel app, that trade must be priced explicitly before adoption, because Carbon is the framework's ambient time type (now(), Eloquent date casts, validation rules, whereDate binding paths, queued job timestamps, Passport/Sanctum TTLs).

Integration feasibility. Feasible and cheap to start, because there is no framework coupling to fight: composer require cakephp/chronos, and the three genuinely differentiating capabilities are immediately usable — first-class date-only and time-only value objects, DST-safe elapsed arithmetic (addElapsedHours/Minutes/Seconds in 3.5.0, documented as true inverses of diffIn*), and a PSR-20 ClockFactory for injectable "now". The PSR-20 clock is the cleanest seam into Laravel: bind Psr\Clock\ClockInterface to ClockFactory in a service provider and inject it into domain services. The friction appears at persistence and serialization boundaries, where conversion to native DateTimeImmutable or a formatted string becomes mandatory.

Technical risk.

  • Interop risk (high, bounded). No DateTimeInterface means no direct hand-off to Eloquent casts, the query builder, Symfony/Laravel validation, or third-party SDKs that accept DateTimeInterface. Mitigation is a thin boundary adapter (.toNativeDateTimeImmutable(), .format('Y-m-d')) applied consistently — architecturally fine, but it must be a rule, not a habit.
  • Two-time-library risk (high, chronic). Carbon stays in the app regardless. Two time libraries means two idioms, two test-mocking mechanisms, and reviewer ambiguity about which type a service should return.
  • Immutability misuse (medium). The README's own example — $date->modify('+2 hours'); silently discarding the result — is the classic failure mode. Static analysis and code review catch some of it; not all.
  • Timezone semantics (medium). ChronosDate uses the server default timezone for its zeroed time component. Correct for calendar dates, hazardous in a multi-region deployment where "server default" is an implicit variable. Requires an explicit timezone policy (date_default_timezone_set('UTC')) as a prerequisite.
  • Version skew (medium). 2.x → 3.x removes mutable classes and Carbon compatibility shims; 2.5.1 requires PHP 8.4 for the createFromTimestamp() signature match. Mixed majors across a monorepo or shared package set will produce confusing type errors.
  • Patch-level regressions (low but evidenced). 3.3.2 introduced a createFromFormat/testNow regression that 3.3.3 reverted as a BC break. Pin exact versions and let CI gate minor/patch bumps.
  • Data-quality caveat on the inputs. The dataset reports Dependents: 0, which is not credible for a package the CakePHP framework itself consumes — treat that field as unmetured, not as evidence of low adoption. The Last release: 2026-09-06 timestamp also appears forward-dated; verify against Packagist before using release cadence in any planning commitment. The 1,362 stars and 36.47 composite score describe a mature, modest-footprint utility, not a fast-growing one.

Key questions.

  1. Which bounded contexts actually need date-only or time-only semantics (bookings, business hours, recurring schedules, billing periods), versus an instant-in-time timestamp?
  2. How many interfaces in our codebase — ours and vendors' — type-hint DateTimeInterface and would reject a Chronos object?
  3. Do we store date-only values as DATETIME at midnight today? If so, is a data migration in scope, or do we adapt at the boundary only?
  4. What is the correctness cost of the current DST behavior in interval math (SLA timers, on-call rotations, proration), and is addElapsed* the fix?
  5. Who owns the "which time type where" convention, and how is it enforced (architecture tests, PHPStan rules, review checklist)?
  6. Exit cost: if we standardize and later revert, is the conversion layer complete enough to swap back to CarbonImmutable?
  7. PHP version floor across all services versus the Chronos version map — can we standardize on 3.x everywhere, or do we need 2.x on legacy services?

Integration Approach

Stack fit. Keep Laravel's native time handling at the edges and adopt Chronos inside the domain. Concretely: Carbon remains the type of Eloquent date casts, now(), validation, and HTTP serialization; Chronos types are used in services, value objects, and business rules where immutability, date-only, or time-only semantics are the point. Bind Psr\Clock\ClockInterface to Cake\Chronos\ClockFactory as a container singleton so now() becomes an injected dependency rather than a global — this is the single highest-value, lowest-risk change and it decouples the domain from both Carbon and Chronos.

Migration path (incremental, reversible).

  1. Pilot, not rollout. Pick one bounded context with genuine date/time semantics — recurring bookings, business hours, subscription billing proration, or on-call rotation — and implement it in Chronos behind existing interfaces. Success criteria: fewer date-related defects and no timezone regressions in that module.
  2. Establish the boundary. Add explicit conversion helpers (Chronos → native DateTimeImmutable / string) and require them at the persistence and serialization edges. Codify with an architecture test that fails if Cake\Chronos\* appears in Eloquent models, controllers, or HTTP resources.
  3. Wire the clock. Register ClockInterface → ClockFactory in a service provider; refactor the pilot module to inject it. Do not attempt to replace now() application-wide.
  4. Harmonize test time. Build one test helper that sets both Carbon and Chronos test-now and resets in finally (prefer Chronos 3.4's scoped withTestNow() inside the helper). Without this, travel() in tests will not affect domain code and you will get flaky, order-dependent suites.
  5. Expand only on evidence. Promote to additional contexts where the date-only/time-only/DST-safe arithmetic benefits recur. Never make Chronos mandatory for general timestamp work.

Compatibility. Confirm the PHP version map against the lowest PHP in the fleet before pinning a major; avoid running 2.x and 3.x in the same dependency graph. Pin exact versions in composer.json and let Renovate/Dependabot open minor bumps as reviewable PRs — the 3.3.2/3.3.3 episode justifies not auto-merging. Treat DateTimeInterface as the interop contract: any boundary that needs it gets a conversion, and that conversion is tested.

Sequencing. Pilot (1 sprint) → boundary adapter + clock binding + test helper (1 sprint, reusable) → 2–3 additional contexts (opportunistic) → convention doc and onboarding material. Total credible effort for a mid-sized team: 4–6 weeks of one engineer's partial time plus review overhead, with the pilot delivering value in week 2.

Operational Impact

Maintenance. Low surface area, MIT license, semantic versioning, and release notes that document behavior changes rather than just commits — a good sign for upgrade predictability. Releases through the 3.5 line are additive and small (startOfHour, toArray, shiftTimezone, comparison methods), which means upgrade cost is mostly "read the notes, run the suite." The real maintenance burden is not the package; it is the internal convention ("when do I use ChronosDate vs. Chronos vs. CarbonImmutable?") and the conversion layer. Budget for a living one-page standard, owned by whoever owns the domain model.

Support. No commercial support tier; issues and PRs go through the CakePHP core team's volunteer cadence, which has been consistent but is not an SLA. Bus factor is concentrated in a handful of named maintainers. For a business-critical scheduling or billing subsystem, that is acceptable because the library is small, MIT, and replaceable — not because support is guaranteed. Mitigate with version pinning and an internal fork-readiness note; the codebase is small enough that a fork is a viable contingency.

Scaling. No runtime, network, or framework coupling; computation is equivalent in cost to native DateTime with modest overhead from wrapper object allocation and immutable copy-on-modify. That is irrelevant for typical request-path use and potentially relevant in tight loops over large date ranges (reporting, recurrence expansion) — measure before optimizing, and prefer arithmetic on native types inside hot loops.

Failure modes to instrument.

  • Discarded immutability results — mutations silently lost. Detect: PHPStan/Psalm at high level, plus targeted review of any ->modify/->add call not assigned or returned.
  • Type errors at the boundary — Chronos passed where DateTimeInterface is required. Detect: architecture tests, plus static analysis with no mixed escape hatches.
  • Timezone drift on date-only values — ChronosDate inheriting a non-UTC server default. Detect: explicit date_default_timezone_set in bootstrap, an assertion test, and a lint of deployment configs differing per region.
  • Test-time desynchronization — Carbon frozen, Chronos not, or vice versa. Detect: the shared helper plus a CI check that no test calls setTestNow directly.
  • Dependency drift — 2.x and 3.x coexisting in a monorepo. Detect: a CI job asserting a single resolved Chronos major.

Ramp-up. Low for anyone fluent in Carbon or DateTime — the API is intentionally familiar, and the modify/add return-value discipline lands within an hour. Two things slow people down: un-learning Carbon shims and mutable idioms (copy-pasted Carbon snippets will not work), and AI coding assistants, which will confidently suggest Carbon methods that do not exist on Chronos and pattern-match toward DateTimeInterface-based code. Ramp-up is therefore roughly half a day of hands-on work plus a short internal note listing the five most common mistakes, and a standing expectation that reviewers check return-value assignment. A single brown-bag session and the convention doc are sufficient; no formal training program is warranted.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels