CRON JOB - Schedule Laravel command for different timezones - Manage for different regions

CRON JOB - Schedule Laravel command for different timezones - Manage for different regions

我正在使用 Laravel 5.8 并且我喜欢自动生成发票应该在周一至周日自动生成。 每个星期天晚上 23:59:00

假设我有

"23:59:00 根据地区时区".

每个商店都与一个地区相关,从地区table你会找到时区。

问题 我应该如何设置 CRON JOB,以便我可以根据我将从 table 获得的时区列表自动生成发票?

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

Using the timezone method, you may specify that a scheduled task's time should be interpreted within a given timezone:

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

我有两个建议;

如果您希望它是静态的,请使用数据库中相应的时区定义每个命令。不同的时区可能有相同的时间,例如 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);

在你的命令里面class;

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

A few zones are offset by 30 or 45 minutes (e.g. Newfoundland Standard Time is UTC−03:30, Nepal Standard Time is UTC+05:45, Indian Standard Time is UTC+05:30 and Myanmar Standard Time is UTC+06:30).

如果你想覆盖其中任何一个,那么最好像这样执行命令

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

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

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