mtdowling/cron-expression
A PHP library for parsing and evaluating cron expressions. Check whether a schedule is due, get next/previous run dates, and iterate occurrences. Supports standard cron fields plus common extensions, useful for job schedulers and task runners.
Installation
composer require mtdowling/cron-expression
Basic Usage
use Cron\CronExpression;
$expression = CronExpression::factory('* * * * *'); // Every minute
$nextRun = $expression->getNextRunDate();
$isDue = $expression->isDue();
CronExpression class is the core. Check the README for syntax examples.First Use Case: Scheduling a Command
$cron = CronExpression::factory('0 12 * * 1'); // Every Monday at noon
if ($cron->isDue()) {
Artisan::call('backup:run');
}
Parsing and Validation
$expression = CronExpression::factory('*/15 * * * *'); // Every 15 minutes
$isValid = $expression->isValid(); // true/false
Time Zone Awareness
$expression = CronExpression::factory('0 0 * * *', new \DateTimeZone('America/New_York'));
$nextRun = $expression->getNextRunDate();
DateTimeZone to handle timezone-specific scheduling.Integration with Laravel Scheduler
// In a custom scheduler command
$schedule = CronExpression::factory('0 3 * * *');
if ($schedule->isDue()) {
// Execute task
}
Recurring Tasks with Context
$expression = CronExpression::factory('0 0 1 * *'); // First of every month
$lastRun = new \DateTime('last month');
$nextRun = $expression->getNextRunDate($lastRun);
DateTime to calculate runs relative to a specific point in time.Dynamic Cron Strings
$userCron = $request->input('cron_expression');
$expression = CronExpression::factory($userCron);
Batch Processing
$expressions = [
CronExpression::factory('* * * * *'), // Every minute
CronExpression::factory('*/5 * * * *'), // Every 5 minutes
];
foreach ($expressions as $expr) {
if ($expr->isDue()) {
// Process
}
}
Logging and Metrics
$expression = CronExpression::factory('0 * * * *');
if ($expression->isDue()) {
Log::info('Cron job triggered', ['expression' => $expression->getExpression()]);
}
Time Zone Mismatches
getNextRunDate() uses the server’s default timezone.DateTimeZone for consistency:
$expression->getNextRunDate(new \DateTime('now', new \DateTimeZone('UTC')));
Invalid Expressions
isValid() returns false.if (!$expression->isValid()) {
throw new \InvalidArgumentException('Invalid cron expression');
}
Edge Cases in Date Calculation
getNextRunDate() may return dates in the past if called with a future DateTime.getPreviousRunDate() or ensure the input DateTime is recent.Daylight Saving Time (DST) Quirks
getNextRunDate().America/New_York).Inspect Parsed Components
$expression = CronExpression::factory('0 0 * * 0'); // Sunday at midnight
$fields = $expression->getFields(); // Array of parsed values
Log Cron Expressions
Log::debug('Cron expression parsed as:', [
'raw' => $expression->getExpression(),
'fields' => $expression->getFields(),
]);
Custom Field Parsing
Cron\Field\FieldFactory to support non-standard cron syntax (e.g., @hourly).Integration with Laravel Events
event(new CronJobTriggered($expression->getExpression()));
Performance Optimization
$cacheKey = 'cron:' . md5($expression->getExpression());
$nextRun = Cache::remember($cacheKey, 60, function () use ($expression) {
return $expression->getNextRunDate();
});
Testing
Mockery or PHPUnit to mock DateTime for predictable tests:
$now = new \DateTime('2023-01-01 00:00:00');
$expression->getNextRunDate($now);
How can I help you explore Laravel packages today?