CRON作业-为不同时区安排Laravel命令-为不同地区进行管理

时间:2020-05-11 05:58:47

标签: laravel laravel-5 cron jobs

我正在使用Laravel 5.8,我想自动生成应在星期一至星期日自动生成的发票。 每个星期日晚上23:59:00

假设我有

“根据地区时区23:59:00”。

每个商店都与某个地区相关,在地区表中您会找到时区。

问题 我应该如何设置CRON作业,以便可以根据从表中获取的时区列表自动生成发票?。

2 个答案:

答案 0 :(得分:1)

您可以在任务Schedulding中使用timezone() method

使用时区方法,您可以指定计划任务的 时间应该在给定的时区内解释:

$schedule->command('report:generate')
         ->timezone('America/New_York')
         ->at('02:00')

答案 1 :(得分:1)

我有两个建议;

如果希望它是静态的,请从数据库中定义每个命令以及相应的时区。不同的时区可能具有相同的时间,例如Europe/AmsterdamEurope/Berlin

$schedule->command('generate:report')->timezone('one-of-the-timezone')->at('23:59');
$schedule->command('generate:report')->timezone('another-timezone')->at('23:59');
$schedule->command('generate:report')->timezone('yet-another-timezone')->at('23:59');
$schedule->command('generate:report')->timezone('some-other-timezone')->at('23:59');

如果您希望它是动态的,请使其每隔59分钟运行一次,并尝试使用hour将其与时区进行匹配。

$schedule->command('generate:report')->hourlyAt(59);

在您的命令类内部;

public function handle(TimezoneRepository $timezoneRepository)
{
    $timezones = $timezoneRepository->getUniqueTimezones(); // the unique timezones in your database - cache if you want

    foreach ($timezones as $timezone) {
        $date = Carbon::now($timezone); // Carbon::now('Europe/Moscow'), Carbon::now('Europe/Amsterdam') etc..

        if ($date->hour === 23) { // you are in that timezone
            $currentTimezone = $date->getTimezone();
            dispatch(new ReportMaker($currentTimezone)); // dispatch your report maker job
        }
    }
}

使用动态时钟时,您将按照我在开始时所说的那样一次迭代(执行generate:report时)到达多个时区。

  • 可能的缺陷之一是;如果获取时区等的执行时间超过1分钟,则您可能是在00:00而不是23:59。最好以异步方式计算报告并缓存时区列表,以免在执行此循环时遇到问题。

  • 另一个可能的缺陷;

根据wiki;

一些区域相差30或45分钟(例如,纽芬兰标准时间为UTC-03:30,尼泊尔标准时间为UTC + 05:45,印度标准时间为UTC + 05:30,缅甸标准时间为UTC +06:30)。

如果您想涵盖其中任何一个,那么最好执行这样的命令

$schedule->command('generate:report')->cron('14,29,44,59 * * * *');

进行小时和分钟比较,例如;

$date->hour === 23 && $date->hour === 59

相关问题