java定时任务 设置开始时间、结束时间;每周一、四、六执行;并且隔n周执行。最后计算所有执行时间

2024-06-08 07:52

本文主要是介绍java定时任务 设置开始时间、结束时间;每周一、四、六执行;并且隔n周执行。最后计算所有执行时间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java定时任务 设置开始时间、结束时间;每周一、四、六执行;并且隔n周执行。最后计算所有执行时间)

    • 定时任务需求
    • 程序设计
    • 依赖引入
    • 程序
      • 一、计算开始时间那周的周一时间
      • 二、根据executeTime和weekList.get(n),计算每个cron表达式。
      • 三、根据一和二得出的cron表达式和开始时间的那周的周一时间,计算每次定时任务执行的第一次时间。
      • 四、计算所有执行时间
      • 五、测试
      • 六、测试结果
    • 最终代码:

定时任务需求

在一个特殊的项目需求中,我们设计一个定时任务,并算出它所有的执行时间点。

1.有开始时间和结束时间。
2.每周一、四、六执行(动态参数) 执行的时和分HH:mm(动态参数)
3.隔n周执行(动态参数)
4.算每次执行时间。

程序设计

参数类型说明
定时任务开始时间startTimeyyyy-MM-dd
定时任务结束时间endTimeyyyy-MM-dd
执行时间executeTimeHH:mm
周几执行列表weekList: [0,1,2,3,4,5,6] 代表:[周日,周一,周二,周三,周四,周五,周六]cron中 [1,2,3,4,5,6,7] 代表:[周日,周一,周二,周三,周四,周五,周六]
隔几周执行一次interval数字n

依赖引入

        <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency>

程序

一、计算开始时间那周的周一时间

考虑隔周执行,一定要以开始时间那个周的周一为起点,否则时间会算错。

 /*** 开始时间点的周一时间* @param startDate* @return*/public static Date getMonday(Date startDate){/*** 计算给出时间的周一时间*/Calendar calendar = Calendar.getInstance();calendar.setTime(startDate);// 将小时、分钟、秒和毫秒字段设置为0calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);// 将日期设置为本周第一天(默认为周日)的前一天(即周一)calendar.add(Calendar.DAY_OF_WEEK, Calendar.MONDAY - calendar.get(Calendar.DAY_OF_WEEK));// 输出周一0点的时间return calendar.getTime();}

二、根据executeTime和weekList.get(n),计算每个cron表达式。

/***计算cron表达式*@param executeTime  执行时间 HH:mm* @param week   周几* @return cron表达式* @throws ParseException*/public static String createCronStr(String executeTime, Integer week)  {String weekStr = String.valueOf(week + 1);// 设置cron表达式,周三,下午3点30分执行String cronExpression = "0 %1$s %2$s ? * %3$s";String[] times = executeTime.split(":");String hour = times[0];String minute = times[1];return String.format(cronExpression, minute, hour, weekStr);}

三、根据一和二得出的cron表达式和开始时间的那周的周一时间,计算每次定时任务执行的第一次时间。

    /*** 计算下次执行时间* @param cronExpression cron* @param startTime2  开始时间(开始时间的周一时间)* @return* @throws ParseException*/public static  Date getNextExecutionTime(String cronExpression, Date startTime2) throws ParseException {CronExpression cron = new CronExpression(cronExpression);Date nextExecutionTime = cron.getNextValidTimeAfter(startTime2);System.out.println("下次执行时间: " + nextExecutionTime);return nextExecutionTime;}

四、计算所有执行时间

 /**** @param startTime  定时任务开始时间  yyyy-MM-dd* @param endTime    定时任务结束时间  yyyy-MM-dd* @param executeTime  执行时间 HH:mm* @param weekList   周几执行列表  [0,1,2,3,4,5,6] 代表:[周日,周一,周二,周三,周四,周五,周六]* @param interval   隔几周执行一次* @return*/public static List<String> getExecuteTimeList(String startTime, String endTime, String executeTime, List<Integer> weekList, int interval) {List<String> list = new ArrayList<>();try {String startStr = startTime + executeTime;String endStr = endTime + executeTime;SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-ddHH:mm");Date endDate = dateFormat.parse(endStr);Date startDate = dateFormat.parse(startStr);Date now = new Date();//设置日期过期,返回空if (now.getTime() > endDate.getTime()) {return new ArrayList<>();}interval++;for (Integer week : weekList) {String cronExpression = createCronStr(executeTime, week);if (StringUtils.isBlank(cronExpression)) {continue;}Date startTime2 = getMonday(startDate);Date nextExecutionTime = getNextExecutionTime(cronExpression,startTime2);int add = 0;Date nownext = nextExecutionTime;while (nownext.getTime() <= endDate.getTime()) {nownext = new Date(nextExecutionTime.getTime() + add * interval * 7 * 24 * 60 * 60 * 1000L);SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");String str = dateFormat2.format(nownext);if (nownext.getTime() <= endDate.getTime() && nownext.getTime()>=startDate.getTime())  {list.add(str);}add++;}}Collections.sort(list);} catch (ParseException e) {System.out.println("解析异常: " + e.getMessage());e.printStackTrace();}return list;}

五、测试

计算2024-06-15到2026-12-31,每周一、四、六的20:40,并隔一周执行一次的所有执行时间


public static void main(String[] args) {List<Integer> week = new ArrayList<>();week.add(1);week.add(4);week.add(6);long start = System.currentTimeMillis();List<String> list = getExecuteTimeList("2024-06-15", "2026-12-31", "20:40", week, 1);long end = System.currentTimeMillis();System.out.println(end - start + " ms");for(String element : list) {System.out.println(element);}}

六、测试结果

下次执行时间: Mon Jun 10 20:40:00 CST 2024
下次执行时间: Thu Jun 13 20:40:00 CST 2024
下次执行时间: Sat Jun 15 20:40:00 CST 2024
74 ms
2024-06-15 20:40
2024-06-24 20:40
2024-06-27 20:40
2024-06-29 20:40
2024-07-08 20:40
2024-07-11 20:40
2024-07-13 20:40
2024-07-22 20:40
2024-07-25 20:40
2024-07-27 20:40
2024-08-05 20:40
2024-08-08 20:40
2024-08-10 20:40
2024-08-19 20:40
2024-08-22 20:40
2024-08-24 20:40
2024-09-02 20:40
2024-09-05 20:40
2024-09-07 20:40
2024-09-16 20:40
2024-09-19 20:40
2024-09-21 20:40
2024-09-30 20:40
2024-10-03 20:40
2024-10-05 20:40
2024-10-14 20:40
2024-10-17 20:40
2024-10-19 20:40
2024-10-28 20:40
2024-10-31 20:40
2024-11-02 20:40
2024-11-11 20:40
2024-11-14 20:40
2024-11-16 20:40
2024-11-25 20:40
2024-11-28 20:40
2024-11-30 20:40
2024-12-09 20:40
2024-12-12 20:40
2024-12-14 20:40
2024-12-23 20:40
2024-12-26 20:40
2024-12-28 20:40
2025-01-06 20:40
2025-01-09 20:40
2025-01-11 20:40
2025-01-20 20:40
2025-01-23 20:40
2025-01-25 20:40
2025-02-03 20:40
2025-02-06 20:40
2025-02-08 20:40
2025-02-17 20:40
2025-02-20 20:40
2025-02-22 20:40
2025-03-03 20:40
2025-03-06 20:40
2025-03-08 20:40
2025-03-17 20:40
2025-03-20 20:40
2025-03-22 20:40
2025-03-31 20:40
2025-04-03 20:40
2025-04-05 20:40
2025-04-14 20:40
2025-04-17 20:40
2025-04-19 20:40
2025-04-28 20:40
2025-05-01 20:40
2025-05-03 20:40
2025-05-12 20:40
2025-05-15 20:40
2025-05-17 20:40
2025-05-26 20:40
2025-05-29 20:40
2025-05-31 20:40
2025-06-09 20:40
2025-06-12 20:40
2025-06-14 20:40
2025-06-23 20:40
2025-06-26 20:40
2025-06-28 20:40
2025-07-07 20:40
2025-07-10 20:40
2025-07-12 20:40
2025-07-21 20:40
2025-07-24 20:40
2025-07-26 20:40
2025-08-04 20:40
2025-08-07 20:40
2025-08-09 20:40
2025-08-18 20:40
2025-08-21 20:40
2025-08-23 20:40
2025-09-01 20:40
2025-09-04 20:40
2025-09-06 20:40
2025-09-15 20:40
2025-09-18 20:40
2025-09-20 20:40
2025-09-29 20:40
2025-10-02 20:40
2025-10-04 20:40
2025-10-13 20:40
2025-10-16 20:40
2025-10-18 20:40
2025-10-27 20:40
2025-10-30 20:40
2025-11-01 20:40
2025-11-10 20:40
2025-11-13 20:40
2025-11-15 20:40
2025-11-24 20:40
2025-11-27 20:40
2025-11-29 20:40
2025-12-08 20:40
2025-12-11 20:40
2025-12-13 20:40
2025-12-22 20:40
2025-12-25 20:40
2025-12-27 20:40
2026-01-05 20:40
2026-01-08 20:40
2026-01-10 20:40
2026-01-19 20:40
2026-01-22 20:40
2026-01-24 20:40
2026-02-02 20:40
2026-02-05 20:40
2026-02-07 20:40
2026-02-16 20:40
2026-02-19 20:40
2026-02-21 20:40
2026-03-02 20:40
2026-03-05 20:40
2026-03-07 20:40
2026-03-16 20:40
2026-03-19 20:40
2026-03-21 20:40
2026-03-30 20:40
2026-04-02 20:40
2026-04-04 20:40
2026-04-13 20:40
2026-04-16 20:40
2026-04-18 20:40
2026-04-27 20:40
2026-04-30 20:40
2026-05-02 20:40
2026-05-11 20:40
2026-05-14 20:40
2026-05-16 20:40
2026-05-25 20:40
2026-05-28 20:40
2026-05-30 20:40
2026-06-08 20:40
2026-06-11 20:40
2026-06-13 20:40
2026-06-22 20:40
2026-06-25 20:40
2026-06-27 20:40
2026-07-06 20:40
2026-07-09 20:40
2026-07-11 20:40
2026-07-20 20:40
2026-07-23 20:40
2026-07-25 20:40
2026-08-03 20:40
2026-08-06 20:40
2026-08-08 20:40
2026-08-17 20:40
2026-08-20 20:40
2026-08-22 20:40
2026-08-31 20:40
2026-09-03 20:40
2026-09-05 20:40
2026-09-14 20:40
2026-09-17 20:40
2026-09-19 20:40
2026-09-28 20:40
2026-10-01 20:40
2026-10-03 20:40
2026-10-12 20:40
2026-10-15 20:40
2026-10-17 20:40
2026-10-26 20:40
2026-10-29 20:40
2026-10-31 20:40
2026-11-09 20:40
2026-11-12 20:40
2026-11-14 20:40
2026-11-23 20:40
2026-11-26 20:40
2026-11-28 20:40
2026-12-07 20:40
2026-12-10 20:40
2026-12-12 20:40
2026-12-21 20:40
2026-12-24 20:40
2026-12-26 20:40Process finished with exit code 0

最终代码:


import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author dume* @ClassName CronUtils* @description: TODO* @date 2024年06月06日* @version: 1.0*/
public class CronUtils {/**** @param startTime  定时任务开始时间  yyyy-MM-dd* @param endTime    定时任务结束时间  yyyy-MM-dd* @param executeTime  执行时间 HH:mm* @param weekList   周几执行列表  [0,1,2,3,4,5,6] 代表:[周日,周一,周二,周三,周四,周五,周六]* @param interval   隔几周执行一次* @return*/public static List<String> getExecuteTimeList(String startTime, String endTime, String executeTime, List<Integer> weekList, int interval) {List<String> list = new ArrayList<>();try {String startStr = startTime + executeTime;String endStr = endTime + executeTime;SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-ddHH:mm");Date endDate = dateFormat.parse(endStr);Date startDate = dateFormat.parse(startStr);Date now = new Date();//设置日期过期,返回空if (now.getTime() > endDate.getTime()) {return new ArrayList<>();}interval++;for (Integer week : weekList) {String cronExpression = createCronStr(executeTime, week);if (StringUtils.isBlank(cronExpression)) {continue;}Date startTime2 = getMonday(startDate);Date nextExecutionTime = getNextExecutionTime(cronExpression,startTime2);int add = 0;Date nownext = nextExecutionTime;while (nownext.getTime() <= endDate.getTime()) {nownext = new Date(nextExecutionTime.getTime() + add * interval * 7 * 24 * 60 * 60 * 1000L);SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");String str = dateFormat2.format(nownext);if (nownext.getTime() <= endDate.getTime() && nownext.getTime()>=startDate.getTime())  {list.add(str);}add++;}}Collections.sort(list);} catch (ParseException e) {System.out.println("解析异常: " + e.getMessage());e.printStackTrace();}return list;}/***计算cron表达式*@param executeTime  执行时间 HH:mm* @param week   周几* @return cron表达式* @throws ParseException*/public static String createCronStr(String executeTime, Integer week)  {String weekStr = String.valueOf(week + 1);// 设置cron表达式,周三,下午3点30分执行String cronExpression = "0 %1$s %2$s ? * %3$s";String[] times = executeTime.split(":");String hour = times[0];String minute = times[1];return String.format(cronExpression, minute, hour, weekStr);}/*** 计算下次执行时间* @param cronExpression cron* @param startTime2  开始时间(开始时间的周一时间)* @return* @throws ParseException*/public static  Date getNextExecutionTime(String cronExpression, Date startTime2) throws ParseException {CronExpression cron = new CronExpression(cronExpression);Date nextExecutionTime = cron.getNextValidTimeAfter(startTime2);System.out.println("下次执行时间: " + nextExecutionTime);return nextExecutionTime;}/*** 开始时间点的周一时间* @param startDate* @return*/public static Date getMonday(Date startDate){/*** 计算给出时间的周一时间*/Calendar calendar = Calendar.getInstance();calendar.setTime(startDate);// 将小时、分钟、秒和毫秒字段设置为0calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);// 将日期设置为本周第一天(默认为周日)的前一天(即周一)calendar.add(Calendar.DAY_OF_WEEK, Calendar.MONDAY - calendar.get(Calendar.DAY_OF_WEEK));// 输出周一0点的时间return calendar.getTime();}public static void main(String[] args) {List<Integer> week = new ArrayList<>();week.add(1);week.add(4);week.add(6);long start = System.currentTimeMillis();List<String> list = getExecuteTimeList("2024-06-15", "2026-12-31", "20:40", week, 1);long end = System.currentTimeMillis();System.out.println(end - start + " ms");for(String element : list) {System.out.println(element);}}}

这篇关于java定时任务 设置开始时间、结束时间;每周一、四、六执行;并且隔n周执行。最后计算所有执行时间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041586

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听