yarunoka / core
Calendar-aware schedule DSL and pure occurrence query engine
Requires
- php: ^8.4
Requires (Dev)
- azuyalabs/yasumi: ^2.11
- bamarni/composer-bin-plugin: ^1.8
- opis/json-schema: ^2.4
Suggests
- azuyalabs/yasumi: Resolve public holidays automatically, without supplying your own resolver
This package is auto-updated.
Last update: 2026-08-09 17:57:02 UTC
README
Calendar-aware schedule DSL and pure occurrence query engine.
What is Yarunoka?
Real-world schedules are calendar rules, not clock rules. "Payday is the 25th — moved up to the previous business day when that falls on a weekend or a holiday." "Collection day is the second Tuesday of every month." "The poller runs every 90 minutes, but only within business hours." Cron expressions and plain timestamps cannot carry these rules, so they end up as scattered application code — hard to store, hard to display, and impossible for users to edit safely.
Yarunoka is a small JSON DSL — Yrnk — that states such rules as data, plus an engine that answers questions about them:
- A document carries a timezone, a calendar, and a list of
schedules. The calendar is the definitions that give meaning to the
calendar vocabulary: holidays, business holidays, extra business days,
the workweek, business hours, and named date sets of the document's own.
Wherever a date list is expected, a name may be written instead —
either one the calendar defines, or one the document declares under
resolversand the application binds at runtime. - A schedule combines a day expression (days of the month, weekdays,
ordinal weekdays, calendar words such as
holiday, day cycles), an optional shift rule ("the previous business day"), and the times of day (fixed points, grids such as every 90 minutes, or all-day). - The engine is pure. It executes no jobs and persists no state; it answers "does this date-time match?" and "was there an occurrence in this interval?". Firing, catch-up, and throttling remain design decisions of the caller.
The name is the Japanese question やるのか? (yaru no ka?) — roughly "so, do we do it?". That is the question this engine exists to answer.
The DSL is language-independent and specified in the spec repository. This package is its PHP implementation.
Installation
composer require yarunoka/core
Requires PHP 8.4 or newer. No runtime dependencies.
Quick example
use Yarunoka\YrnkEvaluator; use Yarunoka\YrnkParser; $json = <<<'JSON' { "version": "1.0", "timezone": "Asia/Tokyo", "calendar": { "holidays": ["2026-01-01", "2026-07-20"], "business_holidays": [], "business_days": [] }, "schedules": [ {"days": [25], "shift": ["prev", "or_same", "business_day"], "times": ["10:00"]} ] } JSON; $document = (new YrnkParser())->parse($json); $payday = $document->schedules[0]; $evaluator = YrnkEvaluator::fromYrnk($document); // 2026-07-25 is a Saturday, so the payday shifts back to Friday the 24th. $evaluator->matches($payday, new DateTimeImmutable('2026-07-24T10:00:00+09:00')); // true $evaluator->matches($payday, new DateTimeImmutable('2026-07-25T10:00:00+09:00')); // false // The poller's question: was there an occurrence since the last run? $lastRunAt = new DateTimeImmutable('2026-07-24T09:55:00+09:00'); $now = new DateTimeImmutable('2026-07-24T10:05:00+09:00'); $evaluator->hasMatchIn($payday, $lastRunAt, $now); // true
Documentation
- Guides — what the package requires, how to install it, and how to read, write, evaluate, and supply dates at runtime
- The spec repository — the DSL
specification. The JSON Schemas under
schema/are a verbatim copy of the spec's (the spec declares that every language implementation carries a copy) - The Laravel bridge is the separate yarunoka/laravel package