在实现定时器的时候,需要用到cron表达式进行时间执行,而这个时间获取的方式大多数都是指定时间。
应用场景:例如在外卖送货的时候,接单20分钟提醒骑手超时。
实现思路:获取20分钟之后的时间Time,然后获取Time的Cron的表达式,添加一个定时器。到20分钟之后进行提醒。

工具类:

package com.timer.util;

import org.apache.commons.lang.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * Cron表达式工具类(quartz类)
 * 符号表示的值:
 * * 表示所有值;
 * ? 表示未说明的值,即不关心它为何值;
 * - 表示一个指定的范围;
 * , 表示附加一个可能值;
 * / 符号前表示开始时间,符号后表示每次递增的值;
 * L("last") ("last") "L" 用在day-of-month字段意思是 "这个月最后一天";
 * W("weekday") 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)
 * @author lenovo
 */
public class CronUtil {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");

    /**
     * 年 (可选) 留空
     * 允许的特殊字符:留空, 1970-2099 , - * /
     */
    private String year;
    /**
     * 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
     * 允许的特殊字符:1-7 或者 SUN-SAT , - * ? / L C #
     */
    private String week;
    /**
     * 月  可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * 允许的特殊字符:1-12 或者 JAN-DEC , - * /
     */
    private String month;
    /**
     * 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * 允许的特殊字符:1-31 , - * ? / L W C
     */
    private String day;
    /**
     * 时 可以用数字0-23表示
     * 允许的特殊字符:0-23, - * /
     */
    private String hour;
    /**
     * 分 可以用数字0-59 表示
     * 允许的特殊字符:0-59,- * /
     */
    private String minutes;
    /**
     * 秒 可以用数字0-59 表示
     * 允许的特殊字符:0-59,- * /
     */
    private String seconds ;

    /***
     *  日期转换cron表达式 例如 "0 07 10 15 1 ? 2016"
     * @param date 时间点
     * @return
     */
    public static String getCron(Date date) {
        String formatTimeStr = null;
        if (Objects.nonNull(date)) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    /**
     * 获取指定日期的cron表达式
     * @param year 年
     * @param week 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
     * @param month 月 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 可以用数字0-23表示
     * @param minutes 分 可以用数字0-59 表示
     * @param seconds 秒 可以用数字0-59 表示
     * @return
     */
    public static String getCron(String year,String week,String month,String day,String hour,String minutes,String seconds) {
        return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
    }

    /**
     * 获取指定日期的cron表达式
     * @param week 星期 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
     * @param month 月 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 可以用数字0-23表示
     * @param minutes 分 可以用数字0-59 表示
     * @param seconds 秒 可以用数字0-59 表示
     * @return
     */
    public static String getCron(String week,String month,String day,String hour,String minutes,String seconds) {
        return getCron("*",week,month,day,hour,minutes,seconds);
    }

    /**
     * 获取指定日期的cron表达式
     * @param month 月 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 可以用数字0-23表示
     * @param minutes 分 可以用数字0-59 表示
     * @param seconds 秒 可以用数字0-59 表示
     * @return
     */
    static String getCron(String month,String day,String hour,String minutes,String seconds) {
        return getCron("?",month,day,hour,minutes,seconds);
    }

    /**
     * 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2 2021-2022
     * @param year 年 使用(year1-year2) year1<=year2
     * @param week 星期 使用(week1-week2) 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
     * @param month 月 使用(month1-month2) 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日  使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
     * @param minutes 分  使用(minutes1-minutes2) 可以用数字0-59 表示
     * @param seconds 秒  使用(seconds1-seconds2) 可以用数字0-59 表示
     * @return
     */
    public static String getCronByRange(String year,String week,String month,String day,String hour,String minutes,String seconds) {
        return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
    }

    /**
     * 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2
     * @param week 星期 使用(week1-week2) 可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
     * @param month 月 使用(month1-month2) 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日  使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
     * @param minutes 分  使用(minutes1-minutes2) 可以用数字0-59 表示
     * @param seconds 秒  使用(seconds1-seconds2) 可以用数字0-59 表示
     * @return
     */
    public static String getCronByRange(String week,String month,String day,String hour,String minutes,String seconds) {
        return getCron("*",week,month,day,hour,minutes,seconds);
    }

    /**
     * 获取指定范围的Cron表达式  例如 13-14 30-31 11-12 20-21 04-05
     * @param month 月 使用(month1-month2) 可以用0-11 或用字符串  “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
     * @param day 日  使用(day1-day2) 可以用数字1-31 中的任一一个值,但要注意一些特别的月份
     * @param hour 时 使用(hour1-hour2) 可以用数字0-23表示
     * @param minutes 分  使用(minutes1-minutes2) 可以用数字0-59 表示
     * @param seconds 秒  使用(seconds1-seconds2) 可以用数字0-59 表示
     * @return
     */
    static String getCronByRange(String month,String day,String hour,String minutes,String seconds) {
        return getCron("?",month,day,hour,minutes,seconds);
    }


}

测试:

public static void main(String[] args) {
        Date date = new Date();
        String cron = getCron(date);
        System.out.println("当前时间"+date.toString()+"的表达式"+cron);
        //2023年3月21日11点50分20秒执行
        System.out.println("2023年3月21日11点50分20秒执行的表达式"+getCron("2023","*","3","21","11","50","20"));
        //-的使用方法 4月20日8点-4月20日10点 整点执行一次
        System.out.println("时间的表达式"+getCronByRange("4","20","8-10","0","0"));
        // /的使用方法 每隔1分钟执行一次
        System.out.println("每隔1分钟执行一次的表达式"+getCronByRange("*","*","*","*/1","*"));
        // ,的使用方法 每天上午10点,下午2点,4点
        System.out.println("每天上午10点,下午2点,4点的表达式"+getCronByRange("*","*","10,14,16","0","0"));
        // L的使用方法 每个月最后一天的10点15分0秒触发任务
        System.out.println("每个月最后一天的10点15分0秒的表达式"+getCronByRange("*","L","10","15","0"));
        // W的使用方法 每个月最接近6号的工作日10点15分0秒触发任务(工作日范围:周一到周五)6号是周一到周五某一天,就在六号执行;如果6号是周六,周五执行,如果6号是周日,周一执行
        System.out.println("每天上午10点,下午2点,4点的表达式"+getCronByRange("*","6W","10","15","0"));
    }

输出结果:

java 定时任务cron表达式 java定时器cron_字符串