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);
    }
}
View Code

 

posted @ 2024-05-31 11:28  wq9  阅读(472)  评论(0编辑  收藏  举报