yarunoka/core

Calendar-aware schedule DSL and pure occurrence query engine

Maintainers

Package info

github.com/yarunoka-dev/php-core

Documentation

pkg:composer/yarunoka/core

Transparency log

Fund package maintenance!

yarunoka-dev

Statistics

Installs: 53

Dependents: 1

Suggesters: 0

Stars: 3

Open Issues: 1

1.2.0 2026-08-09 07:43 UTC

README

CI Latest Version PHP Version License Downloads

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 resolvers and 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

License

MIT