简体   繁体   中英

One time custom cron schedule in laravel

I want to run a cron just once at a custom date & time entered by the user in a form. What is the best way to do this?

I found that a custom cron can be scheduled in laravel like this

->cron(‘* * * * * *’);             

Run the task on a custom Cron schedule.

But I could not find the time format what the * mean.

Or much simpler, can it be done like this by adding the date and time.

->at('28/04/2020 13:00');

How can this be done?

Laravel documentation has in detail description on that in here Task Scheduling

You can add your scheduling logic in a given file

App\Console\Kernel

Currently, laravel have the kind of functionality that exactly match your requirement but it provide a ->monthlyOn(23, '13:00'); via which you can achieve your requirement, It Run the task every month on the 23th at 13:00

protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {

        })->->monthlyOn(23, '13:00');
    }

The above code runs the task every month on the 23th at 13:00 hours server time.

For your purpose you can change cron scheduling as given below

00 13 28 APR Fri *

1st * Minute
2nd * Hour
3rd * Day of the Month
4th * Month of the Year
5th * Day of the Week
6th * Year    

you can easily do that with when() method

    $schedule->command('command')->when(function (){
        return Carbon::create(2020,4,28,13)->isPast();
    });

@the_hasanov answer is the closest one but it's not complete:

Using his method will run the closure every minute after the date you want!

There is -at least- two methods to avoid this.

1. Using a "already_runned" status

The first one is to store the "already run" status of the schedule somewhere: database or file and use this kind of schedule:

// Using a scheduled closure here to be explicit
// Setting is a generic model to store configuration data.
//   it could be replaced by Redis or other key/value storage
$schedule->call(function() {
    // Run here the wanted logic
    Setting::create(['name' => 'cron_already_runned', 'value' => true]); // Store the already_runned status
})->when(function (){
    $already_runned = Setting::firstWhere('name', 'cron_already_runned');

    return
        optional($already_runned)->value
        &&
        Carbon::create(2020,4,28,13)->isPast();
});

2. Using two "time-condition" which could be true only once

The second one is to use a double "time-condition" which could be true only once:

$schedule->command('command')->when(function (){
    return
        Carbon::create(2021,4,28,13)->isPast()
        &&
        Carbon::create(2021,4,28,14)->isFuture();
});

Using this method is not 100% safe as it could fail if the server is down when the conditions are met

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM