dragonmantank/cron-expression - last day of the month (PHP)
At 04:30, every day.
Next runs · UTC
- —
- —
- —
- —
- —
Calendar
September 2026 · UTC
0 runs
About this tool
dragonmantank/cron-expression - the PHP cron parser behind Laravel scheduling, Symfony Scheduler and most modern PHP schedulers - supports the L modifier in the day-of-month field. 0 0 L * * fires at midnight on the last day of every month.Direct library usage
<?php
require 'vendor/autoload.php';
use Cron\CronExpression;
$cron = new CronExpression('0 0 L * *');
// When does it fire next?
$next = $cron->getNextRunDate();
echo $next->format('Y-m-d H:i'); // e.g. "2026-04-30 00:00"
// Is the schedule due right now?
if ($cron->isDue()) {
runMonthEndJob();
}
// Multi-step preview
foreach ($cron->getMultipleRunDates(5) as $date) {
echo $date->format('Y-m-d H:i') . "\n";
}Laravel scheduling example
<?php
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// Using the named helper (Laravel 8+)
$schedule->command('billing:close-month')
->lastDayOfMonth(); // → equivalent to ->cron('0 0 L * *')
// Or with an explicit cron expression
$schedule->command('reports:monthly')
->cron('0 1 L * *') // 01:00 on the last day of every month
->onFailure(function () {
// alerting hook
});
}Laravel's scheduler runs every minute (via a single system cron entry on the server) and dispatches the matching schedule entries. The last-day-of-month job will be picked up correctly because the underlying parser supports L.
Symfony Scheduler example
<?php
use Symfony\Component\Scheduler\Attribute\AsSchedule;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\ScheduleProviderInterface;
use Symfony\Component\Scheduler\Trigger\CronExpressionTrigger;
#[AsSchedule('billing')]
final class BillingSchedule implements ScheduleProviderInterface
{
public function getSchedule(): Schedule
{
return (new Schedule())->add(
CronExpressionTrigger::fromSpec('0 0 L * *')->message(
new CloseMonthMessage(),
),
);
}
}PHP-specific pitfalls
- Server timezone - `getNextRunDate()` uses the PHP default timezone (set via `date_default_timezone_set` or `php.ini`). For UTC consistency, pin it explicitly:
new DateTimeZone('UTC'). - Laravel scheduler precision - the scheduler runs every minute. A last-day-of-month job at 00:00 fires somewhere in the 00:00:00-00:00:59 window, not precisely at the second.
- `isDue()` vs `getNextRunDate()` -
isDue()tests against the current minute;getNextRunDate()looks forward. Don't mix them when testing at the boundary of a minute. - L vs LW - both supported.
LWgives last weekday; useful when month-end falls on a weekend and you want the latest business day instead.
Examples
- 0 18 * * *Every day at 18:00
- 0 */5 * * *Every 5 hours
- 0 18 * * 1-5Weekdays at 18:00
- 0 0 1 * *Once a month, on the 1st at midnight
Cheatsheet
Full cheatsheet| Field | Req. | Range | Wildcards |
|---|---|---|---|
| minute | yes | 0-59 | , - * / |
| hour | yes | 0-23 | , - * / |
| day of month | yes | 1-31 | , - * / |
| month | yes | 1-12 or JAN-DEC | , - * / |
| day of week | yes | 0-6 or names; some dialects use 0-7 or 1-7 — see Dialects | , - * / |
Frequently asked questions
Syntax
Does dragonmantank/cron-expression support the L modifier?
Yes. dragonmantank/cron-expression (the most popular PHP cron parser, used by Laravel, Symfony scheduler and many others) supports the L modifier in the day-of-month field. Use 0 0 L * * for midnight on the last day of every month. The library also supports ?, W and # in compatible positions.
What is the dragonmantank expression for monthly month-end?
Use 0 0 L * *. It fires at midnight on the actual last day of every month, including February 29 in leap years.
Timing
How do I run the dragonmantank month-end job at 23:30?
Use 30 23 L * *. The minute and hour fields set 23:30, while L selects the final calendar day.
Days and months
Does the library support LW (last weekday)?
Yes. 0 0 LW * * fires at midnight on the last weekday of the month - Friday if the last day is Saturday, Friday if Sunday, otherwise the actual last day. Useful for monthly accounting jobs that should never run on weekends.
Does L handle leap years in dragonmantank?
Yes. L resolves from the current month and year, producing February 29 in leap years and February 28 otherwise.
When should I use LW instead of L?
Use LW when the job must run on the final Monday-to-Friday day of the month. Use L when it must run on the final calendar day regardless of weekday.
Timezones and DST
Which timezone determines the last day in dragonmantank?
The timezone used for the date calculation determines the month boundary. Pass an explicit timezone or configure PHP consistently so midnight is evaluated in the intended business zone.
Can DST affect a dragonmantank month-end schedule?
Yes. The selected timezone controls wall-clock occurrences. Prefer a stable hour and make month-end work idempotent in case infrastructure retries around a transition.
Platforms
How do I use last-day-of-month in Laravel scheduling?
Laravel's task scheduler wraps dragonmantank/cron-expression. Use ->cron('0 0 L * *') in your app/Console/Kernel.php schedule method. Or use the named helper: ->lastDayOfMonth() (added in Laravel 8.x), which is equivalent to ->cron('0 0 L * *').
How do I use last-day-of-month in Symfony Scheduler?
Use RecurringMessage::cron('0 0 L * *', $message) or CronExpressionTrigger::fromSpec('0 0 L * *'). Either form schedules the Symfony message for midnight on the last day of each month.
What PHP versions does dragonmantank/cron-expression support?
Current dragonmantank/cron-expression 3.x requires PHP 8.2 or newer. Check the package's version constraints before selecting an older release for an older PHP runtime.
Debugging
How do I check whether the dragonmantank month-end job is due?
Create new CronExpression('0 0 L * *') and call isDue() with the target time. It checks whether that minute matches the expression.
How do I preview upcoming dragonmantank month ends?
Call getMultipleRunDates(count) on the month-end expression. Inspecting several dates confirms February and varying month lengths before deployment.
How should I prevent duplicate PHP month-end work?
Use an idempotency key based on the accounting month and a lock around the critical section. Cron syntax controls timing, not retries or concurrent workers.
Crontap
Can Crontap run a dragonmantank last-day schedule?
Yes. You can invoke an HTTP-backed PHP month-end job from Crontap; verify L support in the target scheduler and retain application-level idempotency.
Write the cron here. Run it on Crontap.
Point Crontap at any URL. Pick any cron. Done.
WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.
1.9k+ teams · Free forever tier · No credit card