assoconnect/php-date
A lightweight PHP AbsoluteDate object for handling dates without time or timezone concerns. Built on DateTime, it represents a simple calendar day—perfect for birthdays and other timezone-agnostic dates—with easy formatting and timezone-aware creation.
TimeTraveler::addMonthWithReference() now matches v2.14.1 arithmetic again: after $from is advanced by one month, the result is realigned onto the reference day-of-month.TimeTraveler domain class performing reference-anchored calendar arithmetic, and (c) a test suite using PHPUnit #[DataProvider] attributes — i.e., PHP 8 attribute syntax and PHPUnit 10+, which implies a modern PHP floor and a real (not nominal) test suite. This upgrades the earlier "no visible repository / unknown coverage" concern.addMonthWithReference() solves the classic bounded-month problem: advancing a date by n months while pinning to a reference day-of-month, with clamping at month end (Jan 31 → Feb 28/29). That is precisely the logic behind:
Carbon's addMonth()/addMonthsNoOverflow() cover adjacent but not identical ground — Carbon has no first-class notion of a persisted reference day that must be re-applied after every advance. If our domain needs that anchor to remain stable across a chain of additions, this is genuine, non-trivial differentiation. If we only need single-step month addition, Carbon remains sufficient and this package is unwarranted coupling.#[DataProvider] attributes indicate PHPUnit 10+ in dev requirements and PHP 8.1+ in practice. Re-confirm in composer.json: actual PHP floor, Carbon major constraint, and whether ext-intl or ext-calendar is a hard requirement. Verify it does not co-require a second date library we already depend on.addMonthWithReference() and its siblings across month-end, leap-year, and DST boundaries." Because upstream has already changed this behavior once, our tests must be golden/characterization tests, not merely coverage: assert exact output dates, not properties, for a matrix of (from-date, months, reference day) tuples. Port the upstream #[DataProvider] cases into our own suite so a future upstream revert or re-revert fails our build, not production.composer update is a potential silent recalculation of billing dates, renewal dates, or period boundaries. Mitigation: exact version pinning (2.15.1, not ^2.15) for anything on a money or compliance path, plus a mandatory changelog read before bumps.composer update — it requires a code and knowledge audit.$months; $months = 0. These are the cases that produce wrong invoices.addMonthWithinReference-family methods require a major bump? Get this in writing (issue/PR) before committing to the dependency.Carbon::addMonthsNoOverflow() does not, given we must persist our own reference day either way?addMonthWithReference()? Diff the two tags to be certain the revert was complete.Carbon as the default for parsing, formatting, storage, and transport; reserve this package for the anchor-preserving advance operation it uniquely provides.TimeTraveler directly from models, jobs, or controllers. Introduce one internal class — e.g. App\Support\Billing\PeriodAdvancer — that exposes advance(DateTimeImmutable $from, int $months, int $referenceDay): DateTimeImmutable. This is the single seam where a revert, a future semantic change, or a full replacement by hand-rolled logic can be absorbed without a codebase-wide sweep.addMonthWithReference, TimeTraveler, and any locally written month-arithmetic helpers introduced since v2.15.0.Carbon output and logging divergences."assoconnect/php-date": "2.15.1" for money/compliance paths. ^2.15 is not acceptable for this dependency given the observed patch-level behavior change. ~2.14.1 || 2.15.1 only if you have verified 2.14.1 and 2.15.1 are behaviorally identical on your cases.#[DataProvider] cases verbatim.2.15.0 or wrote compensating logic, revert it now and regression-test.TimeTraveler.^ constraints out of habit.App\Support should know TimeTraveler exists.Carbon) and "advance a date while preserving a reference day-of-month" (this package). The most common failure will be using the package where plain Carbon is correct, or vice versa, silently producing off-by-a-day period boundaries.TimeTraveler for class-level properties before running it in long-lived queue workers.now(). Confirm the methods are pure functions of their arguments; non-determinism here would produce divergent renewal dates across servers — a hard-to-diagnose, high-cost failure.TimeTraveler usage outside App\Support is rejected.#[DataProvider] covering month-end clamping, leap years, negative and zero month deltas, and chain-of-additions behavior. Add one test that asserts the pinned version's arithmetic explicitly, so a composer update breaking it fails CI with an obvious message pointing at the ADR.Carbon-based fallback path alive until a full cycle of divergence logs is clean, and add a one-line pre-bump checklist item: "Read the changelog for any release touching TimeTraveler."How can I help you explore Laravel packages today?