mybuilder/cronos
Cronos is a Laravel-friendly task scheduling package for defining, running, and monitoring cron-style jobs from your app. Organize recurring tasks, trigger them on demand, and manage schedules with a clean API and sensible defaults.
Installation
composer require mybuilder/cronos
Add to composer.json if not using Composer:
"require": {
"mybuilder/cronos": "^1.0"
}
Basic Usage
use Cronos\CronExpression;
$expression = CronExpression::factory('* * * * *'); // Every minute
$nextRun = $expression->getNextRunDate(); // Get next execution time
First Use Case Validate a cron expression in a Laravel request:
use Cronos\CronExpression;
use Illuminate\Http\Request;
public function validateCron(Request $request)
{
$expression = $request->input('cron_expression');
$isValid = CronExpression::isValidExpression($expression);
return response()->json(['valid' => $isValid]);
}
Dynamic Cron Validation
public function storeCronJob(Request $request)
{
$expression = $request->input('cron_expression');
$cron = CronExpression::factory($expression);
if (!$cron->isValid()) {
return back()->withErrors(['cron_expression' => 'Invalid cron syntax']);
}
// Save to DB or process further
}
Next Run Calculation
public function getNextRun(DateTime $currentTime = null)
{
$cron = CronExpression::factory('0 12 * * 1'); // Every Monday at noon
$nextRun = $cron->getNextRunDate($currentTime ?? now());
return $nextRun->format('Y-m-d H:i:s');
}
Timezone Handling
$cron = CronExpression::factory('* * * * *', 'America/New_York');
$nextRun = $cron->getNextRunDate();
Artisan::schedule() for dynamic cron jobs:
$schedule->command('my:command')->cron(CronExpression::factory('* * * * *')->getExpression());
Cron rule:
use Cronos\CronExpression;
use Illuminate\Validation\Rule;
$rules = [
'cron_expression' => [
'required',
function ($attribute, $value, $fail) {
if (!CronExpression::isValidExpression($value)) {
$fail('The '.$attribute.' format is invalid.');
}
}
]
];
return response()->json([
'expression' => $cron->getExpression(),
'next_run' => $cron->getNextRunDate()->toIso8601String(),
'timezone' => $cron->getTimezone()->getName(),
]);
Timezone Ambiguity
$cron = CronExpression::factory('* * * * *', 'Europe/London');
$cron->getTimezone()->getName(); // Verify timezone
Edge Cases in Validation
CronExpression::isValidExpression() may return true for syntactically correct but logically invalid expressions (e.g., * * * * * *).$parts = explode(' ', $expression);
if (count($parts) !== 5 && count($parts) !== 6) {
return false;
}
DateTime Precision
getNextRunDate() returns a DateTime object. Ensure your Laravel models/DB fields handle microseconds if needed:
$nextRun = $cron->getNextRunDate()->setTimezone('UTC');
\Log::debug('Cron expression:', [
'raw' => $expression,
'parsed' => CronExpression::factory($expression)->getParts(),
]);
now()
Pass a fixed DateTime to isolate time-related bugs:
$fixedTime = new DateTime('2023-01-01 00:00:00');
$nextRun = $cron->getNextRunDate($fixedTime);
Custom Parsing
Extend Cronos\CronExpression for non-standard formats (e.g., @hourly):
if (str_starts_with($expression, '@')) {
return match ($expression) {
'@hourly' => '* * * * *',
'@daily' => '0 0 * * *',
// ...
default => throw new \InvalidArgumentException('Unknown shorthand'),
};
}
Laravel Service Provider Bind Cronos to the container for global access:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(CronExpression::class, function () {
return CronExpression::factory('* * * * *');
});
}
Database Storage Store cron expressions as strings in DB, but validate on retrieval:
$job = Job::find($id);
$cron = CronExpression::factory($job->cron_expression);
if (!$cron->isValid()) {
$job->forceFill(['cron_expression' => '* * * * *'])->save();
}
$cacheKey = 'cron:'.$expression;
$cron = Cache::remember($cacheKey, now()->addHours(1), function () use ($expression) {
return CronExpression::factory($expression);
});
How can I help you explore Laravel packages today?