cron表达式转化成时间
1. 整体流程
使用Java将cron表达式转化成时间的过程可以分为以下几个步骤:
下面将详细介绍每个步骤的具体操作和所需代码。
2. 解析cron表达式
在Java中,我们可以使用第三方库cron-utils来解析cron表达式。首先,你需要在项目中引入cron-utils的依赖,例如使用Maven:
<dependency> <groupId>com.cronutils</groupId> <artifactId>cron-utils</artifactId> <version>8.0.0</version> </dependency>
然后,你可以使用如下代码解析cron表达式并创建一个Cron对象:
import com.cronutils.model.Cron; import com.cronutils.parser.CronParser; String cronExpression = "0 0 12 * * ?"; CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ)); Cron cron = parser.parse(cronExpression);
在上述代码中,我们使用CronDefinitionBuilder来创建Cron对象,并指定Cron表达式的类型为Quartz。
3. 计算时间
一旦我们获得了Cron对象,我们可以使用它来计算时间。cron-utils提供了方便的方法来计算下一个或上一个执行时间。
import com.cronutils.model.time.ExecutionTime; ZonedDateTime now = ZonedDateTime.now(); ExecutionTime executionTime = ExecutionTime.forCron(cron); ZonedDateTime nextExecution = executionTime.nextExecution(now).orElse(null);
在上述代码中,我们使用ExecutionTime对象的nextExecution方法来计算给定时间之后的下一个执行时间。
4. 输出结果
最后,我们可以将计算得到的时间打印出来。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedTime = nextExecution.format(formatter); System.out.println("下一个执行时间:" + formattedTime);
上述代码中,我们使用DateTimeFormatter来定义时间的格式,并将下一个执行时间按照该格式转化成字符串。
import com.cronutils.model.Cron; import com.cronutils.parser.CronParser; import com.cronutils.model.CronType; import com.cronutils.model.time.ExecutionTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class CronExpressionConverter { public static void main(String[] args) { String cronExpression = "0 0 12 * * ?"; CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ)); Cron cron = parser.parse(cronExpression); ZonedDateTime now = ZonedDateTime.now(); ExecutionTime executionTime = ExecutionTime.forCron(cron); ZonedDateTime nextExecution = executionTime.nextExecution(now).orElse(null); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedTime = nextExecution.format(formatter); System.out.println("下一个执行时间:" + formattedTime); } }
以上就是将cron表达式转化成时间的整个过程。通过使用cron-utils库,我们可以方便地解析cron表达式,并计算出下一个执行时间。
https://blog.51cto.com/u_16175492/9281169?_refluxos=a10
结合 cron 和redis 自定义定时任务
package com.hainei.samp.config; import com.cronutils.model.Cron; import com.cronutils.model.CronType; import com.cronutils.model.definition.CronDefinitionBuilder; import com.cronutils.model.time.ExecutionTime; import com.cronutils.parser.CronParser; import com.hainei.samp.common.schedule.ScheduleQuartzJobDetail; import com.hainei.samp.common.schedule.ScheduleQuartzJobLogService; import com.hainei.samp.common.utils.StringUtils; import com.hainei.samp.dao.mapper.target.TargetTaskMapper; import com.hainei.samp.pojo.BO.target.TargetTaskQueryBO; import com.hainei.samp.pojo.VO.target.TargetTaskVO; import com.hainei.samp.pojo.model.target.TargetTask; import com.hainei.samp.service.base.RedisService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.*; /** * @author: wq * @date: 2024-06-04 10:29 * @description: */ @Component @Slf4j public class TaskRunner implements CommandLineRunner { @Autowired private RedisService redisService; @Autowired private ScheduleQuartzJobLogService scheduleQuartzJobLogService; @Autowired private TargetTaskMapper targetTaskMapper; private static final Byte IS_RAN = 1; private static final Byte IS_PUBLISHED = 1; private static final String TARGET_TASK_PREFIX = "target-task:"; private static final SimpleDateFormat Y_M_D_H_M_S = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static final String SUCCESS = "success"; private static final String ERROR = "error"; private static final String SQL_EXECUTOR = "sqlExecutor"; @Override @SneakyThrows public void run(String... args){ while (true){ Date currentDate = new Date(); TargetTaskQueryBO queryBO = new TargetTaskQueryBO(); queryBO.setIsRan(IS_RAN); queryBO.setIsPublished(IS_PUBLISHED); List<TargetTaskVO> targetTasks = targetTaskMapper.selectListByCondition(queryBO); targetTasks.stream().filter(Objects::nonNull).forEach(targetTask -> { String redisTaskId = TARGET_TASK_PREFIX + targetTask.getId(); String nextTimeStr = (String) redisService.get(redisTaskId); if(StringUtils.isNotEmpty(nextTimeStr)){ Date nextTime = null; try { nextTime = Y_M_D_H_M_S.parse(nextTimeStr); } catch (ParseException e) { e.printStackTrace(); } if(currentDate.compareTo(nextTime) >= 0){ ScheduleQuartzJobDetail scheduleQuartzJobDetail = new ScheduleQuartzJobDetail(); log.info("======定时任务开始执行======"); List<Map> sql = null; long startTimeMillis = 0; try { startTimeMillis = System.currentTimeMillis(); scheduleQuartzJobDetail.setExecuteTime(LocalDateTime.now()); sql = targetTaskMapper.sql(targetTask.getComputeStatement()); scheduleQuartzJobDetail.setResult(SUCCESS); } catch (Exception e) { e.printStackTrace(); scheduleQuartzJobDetail.setResult(ERROR); scheduleQuartzJobDetail.setErrorStackTrace(e.toString()); } finally { long endTimeMillis = System.currentTimeMillis(); nextExecute(targetTask,redisTaskId); scheduleQuartzJobDetail.setGmtCreatedOn(LocalDateTime.now()); scheduleQuartzJobDetail.setId(targetTask.getId()); scheduleQuartzJobDetail.setExecuteId(UUID.randomUUID().toString().replaceAll("-","").toString()); scheduleQuartzJobDetail.setBeanName(SQL_EXECUTOR); scheduleQuartzJobDetail.setName(targetTask.getTargetName()); scheduleQuartzJobDetail.setMethodName(SQL_EXECUTOR); scheduleQuartzJobDetail.setDuration(endTimeMillis-startTimeMillis); scheduleQuartzJobLogService.startExecute(scheduleQuartzJobDetail); } } } else { nextExecute(targetTask,redisTaskId); } }); } } void nextExecute(TargetTaskVO targetTask,String redisTaskId){ CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ)); Cron cron = parser.parse(targetTask.getCron()); ZonedDateTime now = ZonedDateTime.now(); ExecutionTime executionTime = ExecutionTime.forCron(cron); ZonedDateTime nextExecution = executionTime.nextExecution(now).orElse(null); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedTime = nextExecution.format(formatter); log.info("下一个执行时间 <======> "+formattedTime); redisService.set(redisTaskId,formattedTime); } }
个人学习笔记,记录日常学习,便于查阅及加深,仅为方便个人使用。