Symfony 4下JMoseCommandScheduler如何不修改源码指定时区?
解决JMoseCommandScheduler定时任务绑定特定时区(不修改Bundle源码)
要实现这个需求,你可以通过重写Bundle自带的ExecuteCommand并覆盖原服务的方式完成,无需修改Bundle源码,具体步骤如下:
1. 创建自定义的ExecuteCommand类
在你的Symfony项目中新建命令类,继承原Bundle的ExecuteCommand,并重写execute方法,仅修改时区相关代码行:
<?php namespace App\Command\Scheduler; use JMose\CommandSchedulerBundle\Command\ExecuteCommand as BaseExecuteCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class ExecuteCommand extends BaseExecuteCommand { protected function execute(InputInterface $input, OutputInterface $output) { foreach ($this->commandSchedulerManager->getCommandsToExecute() as $command) { try { $cron = \Cron\CronExpression::factory($command->getCronExpression()); // 替换此行,添加目标时区参数 $nextRunDate = $cron->getNextRunDate($command->getLastExecution(), 0, false, 'Europe/Paris'); // 以下保留原方法的其余逻辑,无需修改 if ($nextRunDate <= new \DateTime()) { $this->logger->info( sprintf('Execute command : %s (id: %d)', $command->getName(), $command->getId()) ); $returnCode = $this->executeCommand($command, $input, $output); $command->setLastExecution(new \DateTime()); $command->setReturnCode($returnCode); $command->setLastReturnMessage($this->getLastCommandMessage()); $this->entityManager->persist($command); } } catch (\Exception $e) { $this->logger->error($e->getMessage()); } } $this->entityManager->flush(); return 0; } }
2. 在服务配置中覆盖原Bundle的命令服务
打开config/services.yaml,添加以下配置,将原Bundle的ExecuteCommand服务替换为你自定义的类:
services: # 覆盖JMoseCommandSchedulerBundle的ExecuteCommand服务 JMose\CommandSchedulerBundle\Command\ExecuteCommand: class: App\Command\Scheduler\ExecuteCommand arguments: - '@doctrine.orm.entity_manager' - '@jmose_command_scheduler.manager.command_scheduler' - '@logger' - '@?lock.factory' tags: - { name: console.command }
3. 验证效果
运行定时任务执行命令:
php bin/console scheduler:execute
此时任务的下次运行时间将基于Europe/Paris时区计算,全局PHP时区无需修改,也不会改动Bundle源码。
内容的提问来源于stack exchange,提问作者Cedric
相关产品推荐
相关产品推荐

