khill/php-duration
A PHP library for parsing and formatting durations. Turn strings like "1h 30m" or "2 days" into seconds, and convert seconds back into readable, human-friendly duration strings, with support for localization.
Architecture fit. khill/php-duration is a self-contained utility library (namespace Khill\Duration) that converts a duration between three representations: colon format (HH:MM:SS), human-readable (2 hours 15 minutes), and integer seconds. There is no service provider, no config file, no facade, and no framework coupling — it is a pure leaf dependency. Architecturally it belongs in a value-object/helper layer, not in infrastructure. Its value is entirely contingent on whether we have duration entry and display surfaces: media/asset lengths, time tracking, SLA and timeout displays, training content runtimes, scheduling lead times, billing increments. Where those exist, it replaces scattered gmdate('H:i:s', $seconds), DateInterval arithmetic, and ad-hoc regex parsers. Where they don't, the value is near zero regardless of price.
Integration feasibility. composer require khill/php-duration, then use directly — PSR-4 autoload, MIT license, no transitive dependencies, no native extensions. Effort is measured in hours, not sprints. The one real feasibility question is version compatibility: the last release was March 2021, so the working assumption must be that the declared PHP constraint predates our 8.2/8.3 target and Laravel 10/11. Because there is no framework integration code, Laravel version is largely irrelevant — PHP minor-version compatibility is the gate.
Technical risk. Low blast radius, moderate abandonment risk. Negatives: single maintainer, ~4 years without a release, zero recorded dependents, unclear issue triage. Positives: tiny codebase, permissive license, no I/O, no native code, no dependency graph — which makes "vendor and own it" a one-to-two-day exercise rather than a project. The substantive risks are behavioral, not operational: the human-readable parser's accepted grammar is a product decision we don't control (1.5 hours vs 90m vs 1h30m), and the colon formatter may not encode our assumptions about >24-hour durations, zero-padding, and fractional-second rounding. Treat input validation semantics (throw vs. coerce) as unverified until tested.
Key questions.
Stack fit. Framework-agnostic PHP that sits alongside Laravel rather than inside it. It provides no validation rule, no Eloquent cast, no Blade directive, no config. The correct integration is a thin internal adapter: a DurationCast for Eloquent attributes, a duration validation rule, a Blade component, and an API Resource macro — all delegating to the package behind our own interface so the third-party class never leaks into application code or public API shapes.
Migration path. Start with an inventory of existing duration handling: gmdate/DateInterval formatting, Carbon diffForHumans, hand-rolled parsers, front-end-side formatting. Replace call-site by call-site, prioritizing places where bugs already exist — the classic ones being durations over 24 hours and round-trip fidelity (seconds → human → seconds). Write characterization tests around each call site before swapping the implementation so the change is provably behavior-preserving.
Compatibility. Verify the package's php constraint against our matrix and run its test suite under our PHP version to surface deprecations. Confirm behavior for zero, negative, and sub-second inputs before anything reaches an API response. Note the specific trap that a duration like 25:00:00 is meaningful here but invalid input to gmdate — mixed usage of the two in one codebase produces inconsistent output.
Sequencing.
composer.json and record the fork contingency in the dependency register.Hold off on exposing its output in versioned public API responses until formatting is contractualized by our own tests rather than the package's.
Maintenance. Lowest-effort category: no migrations, no runtime services, no scheduled jobs, no configuration surface. The actual cost is ownership of a stale dependency — budget roughly half a day per year for review and keep the fork option costed at one to two days. Register it with an explicit trigger: "fork if a PHP major makes the tagged release uninstallable."
Support. Community-only, single maintainer, no SLA, documentation limited to the README. Internal ramp-up is trivial — a competent PHP developer is productive in under an hour. The support burden therefore lands on whoever owns the adapter and its docs, not on the upstream project. If duration formatting appears in customer-facing commitments, we own that specification.
Scaling. Negligible. Pure in-process string manipulation with no I/O, no allocations of consequence, and no external calls. It will never be a throughput bottleneck in request paths, queue workers, or jobs. The only caution is batch parsing inside tight loops — parse once and cache the result.
Failure modes.
Ramp-up. Hours for any PHP developer; no domain knowledge required beyond our own duration conventions. The onboarding artifact that matters is the adapter's docblock and the round-trip test suite — not the package README.
Bottom line: a cheap, genuinely low-risk convenience library with a narrow payoff. Adopt it only where it demonstrably removes duplicated formatting/parsing logic, fence it behind an internal interface, pin the version, and treat it as permanently forkable.
How can I help you explore Laravel packages today?