Skip to content

Custom expression factories

Greg Bowler edited this page May 6, 2026 · 1 revision

The library uses ExpressionFactory to turn the schedule part of each crontab line into an Expression object.

Most projects will use the built-in CronExpression, but we can replace the factory when we need project-specific shorthand.

A custom expression factory is handy when we want to support things such as:

  • extra nickname tokens
  • application-specific schedule words
  • test-only expressions
  • migration paths from an older internal scheduler

Basic shape

ExpressionFactory only needs one method:

use GT\Cron\Expression;
use GT\Cron\ExpressionFactory;

class MyExpressionFactory extends ExpressionFactory {
	public function create(string $expression):Expression {
		// Return a custom Expression here.
	}
}

Example: @start schedule

The repository includes an example of handling @start as "due immediately":

use DateTime;
use GT\Cron\CronExpression;
use GT\Cron\Expression;
use GT\Cron\ExpressionFactory;

$customExpressionFactory = new class extends ExpressionFactory {
	public function create(string $expression):Expression {
		if($expression === "@start") {
			return new class implements Expression {
				public function isDue(DateTime $now):bool {
					return true;
				}

				public function getNextRunDate(?DateTime $now = null):DateTime {
					return clone ($now ?? new DateTime());
				}
			};
		}

		return new CronExpression($expression);
	}
};

Then pass that factory into the parser:

use GT\Cron\CrontabParser;

$parser = new CrontabParser($customExpressionFactory);

Now a crontab can contain:

@start hello
30 * * * * hourly-report

The above example will execute hello at the start of the execution, once. Then it will execute hourly-report at 30 minutes past every hour.

Keep the contract simple

An Expression only needs to answer two questions:

  • is this job due now?
  • when is the next run date?

That small contract keeps custom schedules easy to reason about.

Prefer clarity over cleverness

If a schedule rule is specific to your project, document it near the crontab file or deployment docs as well. Hidden shorthand tends to confuse the next person who reads the schedule.


To see the built-in examples from this repository, continue with Examples.

Clone this wiki locally