Product Decisions This Supports
- Scheduling UX in admin surfaces. Any place a user sees a raw cron string — saved reports, digest emails, webhook retries, recurring invoices, retention policies, backup windows — becomes a plain-language sentence ("Every Monday at 4:00pm"). This is a UX decision, not an engineering one: do we ship raw
0 16 * * 1 or a readable summary? This package makes the readable option a ~1-hour ticket instead of a parser project.
- Roadmap: self-service configuration for non-technical roles. Ops, marketing, finance, and customer-success users configure schedules in most B2B tools. Readable descriptions shift the "what did I just set up?" question from support tickets to the screen itself, and they let you defer a full visual cron builder while still shipping something usable.
- Globalization sequencing. Nineteen shipped locales (
ar, cs, da, de, en, es, fr, hi, lv, nl, pl, pt, ro, ru, sk, ua, vi, zh, zh-TW) plus an optional 24-hour time format mean localized schedule copy is not a blocker for market entry. That changes the calculus on "do we launch this feature in DE/FR/JP-adjacent markets now or after localization?" Locale coverage should still be spot-checked per market — translation quality varies by contributor, and a wrong weekday or am/pm rendering is a visible, embarrassing bug.
- Build vs. buy, with a clear answer. The alternative is a hand-rolled translator: parse five fields, handle
*, ranges, steps, lists, named months/weekdays, pluralize, localize, format time. That is a multi-week job with a long tail of edge cases and no product differentiation. Buying (free, MIT) is correct unless you specifically need Quartz-style syntax or natural-language input.
- Transparency / trust features. Showing a readable schedule alongside the raw expression on job detail pages and in audit logs is a cheap trust win for finance, healthcare, and legal-adjacent buyers where "what exactly runs at 2am?" is a review question. It also shortens debugging: on-call reads the sentence, not the asterisks.
- API and documentation quality. Auto-generated human-readable schedule descriptions in API responses, OpenAPI examples, and help-center articles reduce onboarding friction for integration partners. This is a documentation-debt decision as much as a feature decision.
- Legacy modernization / tech-debt paydown. If a custom cron description helper already exists in the codebase, this is a candidate drop-in replacement that removes maintenance ownership from the team — a small, low-risk consolidation.
- Prioritization signal, honestly read. 316 stars, active releases (through v0.5.1, with PHP 8.4/8.5 test coverage), zero recorded dependents. The active maintenance and contributor-driven locale additions are the good signal; the near-zero dependent count means you are an early-ish adopter, so budget for reading the source rather than relying on a large body of field reports.
When to Consider This Package
Adopt when most of these are true:
- The output is user-facing. Admin panels, settings pages, customer emails, public API responses, help docs, audit exports. If no human outside engineering ever reads the schedule, this package adds a dependency for nothing.
- Schedules are 5-field standard cron. The translator is built for
minute hour day-of-month month day-of-week. It handles the messy parts well — ranges (1-20), steps (*/2, 1/3), lists (0,30), and comma-separated weekdays — but it is a translator, not a full cron engine.
- You need localized schedule copy and don't want to own the translation matrix. Verify the locales you actually ship in; consider contributing fixes upstream rather than forking.
- The team is on a modern PHP runtime. Recent majors dropped PHP 7.x and added strong typing; check your floor before committing.
- You want a small, framework-agnostic dependency. It's a plain PHP package with a static entry point, so it drops into Laravel service providers, Blade views, API resources, or console output equally easily. Wrap it in a thin helper/decorator so the UI stays testable and you can swap implementations later.
- You need description, not authoring. Pair it with a separate cron builder/validator (or your own field-level UI) if users must construct expressions.
Look elsewhere — or scope it out — when:
- You need the reverse direction: natural language → cron, or a visual drag-and-drop schedule editor. Different problem, different package.
- You need extended/Quartz syntax:
L, W, ?, #, six-field with seconds, or @daily-style macros. Unsupported operators may throw or mis-describe — that's a correctness risk, not a missing nicety.
- You need validation, next-run calculation, or timezone semantics. This translates; it does not schedule. Use a cron engine for the "when does it actually fire" question, and be aware descriptions are timezone-agnostic strings.
- You're building a high-stakes scheduling product where a subtly wrong sentence (e.g., ambiguous day-of-month and day-of-week combinations) carries real cost. In that case, adopt it but own a golden-file test suite of your own expressions.
- Third-party dependency review is heavy. MIT is permissive and unblocking, but confirm your security/licensing process accepts a single-maintainer package with a static API surface.
- Your product already exposes a schedule UI that users read fluently — e.g., a developer tool where
*/5 * * * * is the expected idiom. The translation may be noise.
How to Pitch It (Stakeholders)
For executives and product leadership: Every product with recurring behavior eventually shows users a cron expression, and every one of those moments generates a "what does this mean?" support conversation or a misconfigured schedule. This package turns those strings into plain sentences — in nineteen languages, with a one-line API — for free under MIT. The strategic case is threefold: it removes a recurring support and onboarding cost, it unblocks localized launches without a translation project, and it lets us ship self-service scheduling to non-technical users without committing to a full visual scheduler on the roadmap. Cost is a dependency and roughly a day of integration plus tests; the alternative is weeks of parser work that differentiates us in no way. The honest risks are scope, not strategy: it describes schedules rather than validating or generating them, and it covers standard five-field cron only — so it complements, rather than replaces, a scheduler engine.
For engineering: A small, actively maintained, MIT-licensed PHP package with a static CronTranslator::translate($expression, $locale, $use24h) API, strong typing, CI coverage on current PHP versions, and framework-agnostic design. Handles ranges, steps, and lists; ships nineteen locales with an optional 24-hour time format. Integration is a composer require plus a thin wrapper we control. Boundaries to plan around: no natural-language input, no cron generation, no next-run calculation, and no support for extended operators (L, W, ?, #) or seconds-field expressions — we should guard or fall back gracefully on those. Ask: wrap the call behind our own ScheduleDescriber interface with a golden-file test suite over the expressions our product actually permits, so correctness is ours to verify and the dependency stays replaceable.