Java实现自动定时任务配置并判断当天是否需要执行示例

最近接到一个需求,用户要能配置一个定时循环的任务,就是和手机闹钟循环差不多,设置好比如周一、周二、周三,那么在这几天内这个任务就需要自动执行

需求不复杂,首先我需要判断当前是周几,当然用户说了让我看手机闹钟的循环规则,我看了下还有法定工作日和法定节假日这些
所以我们先写个工具类来判断当前日期是否需要执行

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.MonthDay;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Sakura
 * @date 2024/6/20 9:48
 */
public class SchedulerTaskUtil {

    public enum RepeatCycle {
        DAILY,         // 每天
        MONTHLY,       // 每月
        HOLIDAYS,      // 法定节假日
        WORKDAYS,      // 法定工作日
        MONDAY,        // 周一
        TUESDAY,       // 周二
        WEDNESDAY,     // 周三
        THURSDAY,      // 周四
        FRIDAY,        // 周五
        SATURDAY,      // 周六
        SUNDAY         // 周日
    }

    private static final Set<MonthDay> HOLIDAYS = new HashSet<>();

    static {
        // 初始化法定节假日 2024 这个需要定期维护有些麻烦
        HOLIDAYS.add(MonthDay.of(1, 1));  // 元旦
        HOLIDAYS.add(MonthDay.of(2, 10)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 11)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 12)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 13)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 14)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 15)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 16)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 17)); // 春节
        HOLIDAYS.add(MonthDay.of(4, 4)); // 清明节
        HOLIDAYS.add(MonthDay.of(4, 5)); // 清明节
        HOLIDAYS.add(MonthDay.of(4, 6)); // 清明节
        HOLIDAYS.add(MonthDay.of(5, 1)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 2)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 3)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 4)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 5)); // 劳动节
        HOLIDAYS.add(MonthDay.of(6, 8)); // 端午节
        HOLIDAYS.add(MonthDay.of(6, 9)); // 端午节
        HOLIDAYS.add(MonthDay.of(6, 10)); // 端午节
        HOLIDAYS.add(MonthDay.of(9, 15)); // 中秋节
        HOLIDAYS.add(MonthDay.of(9, 16)); // 中秋节
        HOLIDAYS.add(MonthDay.of(9, 17)); // 中秋节
        HOLIDAYS.add(MonthDay.of(10, 1)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 2)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 3)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 4)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 5)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 6)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 7)); // 国庆节
        // 其他假日可以继续添加
    }

    private Set<RepeatCycle> repeatCycles;

    public SchedulerTaskUtil(String repeatCyclesStr) {
        this.repeatCycles = Arrays.stream(repeatCyclesStr.split(","))
                .map(String::trim)
                .map(String::toUpperCase)
                .map(RepeatCycle::valueOf)
                .collect(Collectors.toSet());
    }

    public boolean shouldExecuteToday() {
        LocalDate today = LocalDate.now();
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        MonthDay monthDay = MonthDay.from(today);

        if (repeatCycles.contains(RepeatCycle.DAILY)) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.MONTHLY) && today.getDayOfMonth() == 1) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.HOLIDAYS) && HOLIDAYS.contains(monthDay)) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.WORKDAYS) && !HOLIDAYS.contains(monthDay)
                && dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.MONDAY) && dayOfWeek == DayOfWeek.MONDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.TUESDAY) && dayOfWeek == DayOfWeek.TUESDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.WEDNESDAY) && dayOfWeek == DayOfWeek.WEDNESDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.THURSDAY) && dayOfWeek == DayOfWeek.THURSDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.FRIDAY) && dayOfWeek == DayOfWeek.FRIDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.SATURDAY) && dayOfWeek == DayOfWeek.SATURDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.SUNDAY) && dayOfWeek == DayOfWeek.SUNDAY) {
            return true;
        }

        return false;
    }

    public static void main(String[] args) {
        // 示例:任务在周一和周三执行
        String repeatCyclesStr = "MONDAY,WEDNESDAY";
        SchedulerTaskUtil scheduler = new SchedulerTaskUtil(repeatCyclesStr);

        if (scheduler.shouldExecuteToday()) {
            System.out.println("Today is a repeat day, generate the task.");
            // 生成任务的逻辑
        } else {
            System.out.println("Today is not a repeat day.");
        }
    }
}

执行一下测试方法

在这里插入图片描述
显示今天不是需要重复的一天,因为今天星期四

在这里插入图片描述

给它加上周四

在这里插入图片描述

再执行就对了

在这里插入图片描述
剩下的就好说了,我们只需要加一个定时器就可以

import com.yokea.pro.task.mapper.TaskMapper;
import com.yokea.pro.task.model.po.Task;
import com.yokea.pro.task.util.SchedulerTaskUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Sakura
 * @date 2024/06/20 15:24
 */
@Component
@EnableScheduling
@Slf4j
public class ScheduledTask {

//    每隔1分钟执行一次:0 */1 * * * ?
//    每天22点执行一次:0 0 22 * * ?
//    每月1号凌晨1点执行一次:0 0 1 1 * ?
//    每月最后一天23点执行一次:0 0 23 L * ?
//    每周周六凌晨3点实行一次:0 0 3 ? * L
//    在24分、30分执行一次:0 24,30 * * * ?

    @Autowired
    private TaskMapper taskMapper;


    /**
     * @description: 每天凌晨开始生成周期循环任务
     * @author: Sakura
     * @date: 2024/06/20 16:27
     */
    @Scheduled(cron = "0 0 0 * * ?") // 0 0 0 * * ? 每天0点启动
    @Async
    public void recurrentTasks() {
        log.info("定时生成周期循环任务程序启动——————————————————————————————————————————");
        try {
            // 先获取需要循环启动的周期任务
            List<Task> periodicTaskList = taskMapper.getPeriodicTaskList();
            for (Task task : periodicTaskList) {
                // 判断当前任务当天是否需要重复执行
                SchedulerTaskUtil schedulerTask = new SchedulerTaskUtil(task.getCycle());
                if (schedulerTask.shouldExecuteToday()) {
                    log.info("定时生成周期循环任务程序启动,任务ID:{}", task.getId());
                }
            }
        } catch (Exception e) {
            log.error("定时生成周期循环任务程序启动", e);
        }
    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726859.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【廉颇老矣,尚能饭否】传统的数据仓库是否还能发挥作用?

引言&#xff1a;随着数字化转型的深入和大数据技术的发展&#xff0c;大数据平台、数据中台和和数据湖技术不断涌现&#xff0c;给人感觉传统的数据仓库技术已经过时&#xff0c;廉颇老矣&#xff0c;不能应对新的挑战&#xff0c;在数字化转型中&#xff0c;不能发挥重要作用…

第4章 工程经济评价指标 作业

第4章 工程经济评价指标 作业 一单选题&#xff08;共27题&#xff0c;100分&#xff09; (单选题)利息备付率是指( )与应付利息费用的比值。 A. 息税前利润 B. 利润总额 C. 净利润 D. 营业收入 正确答案: A:息税前利润; (单选题)当净现值( )0时,该项目不可行。 A. < B. …

界面构件开发之RC文件

代码; #include <gtk-2.0/gtk/gtk.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <glib-2.0/glib.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);gtk_rc_parse("./mainrc");GtkWidget *winN…

珈和科技和比昂科技达成战略合作,共创智慧农业领域新篇章

6月14日&#xff0c;四川省水稻、茶叶病虫害监测预警与绿色防控培训班在成都蒲江举办。本次培训班由四川省农业农村厅植物保护站主办&#xff0c;蒲江县农业农村局、成都比昂科技筹办。四川省农业农村厅植物保护站及四川省14个市州36个县植保站负责人进行了观摩学习。 武汉珈…

轻松选购指南:如何挑选3D建模和3D渲染的高效计算机?

选择最适合 3D 建模和3D渲染的计算机可能是一项艰巨的任务&#xff0c;特别是对于初学者来说。有很多因素需要考虑&#xff0c;包括处理器、显卡、内存和存储容量。 如果你计划购买一台计算机或利用3D产品渲染服务&#xff0c;那么你必须了解需要考虑的特性。以下是选择3D建模…

数据结构(中)

完全二叉树的第6层有10个结点&#xff0c;那么有&#xff08;21&#xff09;个叶子结点。 10-52*2*2*2 设树中某结点不是根结点&#xff0c;则离它最近的祖先结点是双亲结点 一颗有5个结点的深度为3的二叉树采用顺序存储方式存储&#xff0c;存储数组的大小至少为7 看深度&…

python自动化系列:自动复制一个工作簿的所有工作表到其他工作簿

作品介绍 作品名称&#xff1a;自动复制一个工作簿的所有工作表到其他工作簿 开发环境&#xff1a;PyCharm 2023.3.4 python3.7 用到的库&#xff1a;os、xlwings 作品效果&#xff1a; 实现过程 一、代码设计 以下是代码的详细说明&#xff1a; 导入模块&#xff1a; …

数字乡村:绘就乡村振兴的智慧新画卷

在乡村振兴战略的宏伟蓝图下&#xff0c;“数字乡村”作为新时代农村现代化的重要抓手&#xff0c;正悄然改变着中国乡村的面貌。本文旨在深度剖析数字乡村建设的核心价值、关键技术、成功案例以及未来展望&#xff0c;为乡村振兴战略提供前瞻性的思考与启示。 数字乡村的核心价…

【Golang - 90天从新手到大师】Day09 - string

系列文章合集 Golang - 90天从新手到大师 String 一个字符串是一个不可改变的字节序列。字符串可以包含任意的数据&#xff0c;但是通常是用来包含人类可读的文本。 len()返回字符串字节数目&#xff08;不是rune数&#xff09;。 通过索引可以访问某个字节值&#xff0c;0…

Vue3 头像是圆形,hover上去时头像出现黑色半透明样式,且中间显示修改两字的实现

实现效果 原头像 hover效果 实现方式 博主在实际开发过程中使用mouseover和mouseout会出现无法点击或hover频繁闪动的问题&#xff0c;故这里采用的是css中的hover&#xff0c;利用hover也能轻松实现上述效果&#xff0c;且完全不会影响点击事件的使用。 <template> &…

Walrus:去中心化存储和DA协议,可以基于Sui构建L2和大型存储

Walrus是为区块链应用和自主代理提供的创新去中心化存储网络。Walrus存储系统今天以开发者预览版的形式发布&#xff0c;面向Sui开发者征求反馈意见&#xff0c;并预计很快会向其他Web3社区广泛推广。 通过采用纠删编码创新技术&#xff0c;Walrus能够快速且稳健地将非结构化数…

实践分享|关于 nebula-stats-exporter 的使用

大家好&#xff0c;这里是玖叁叁&#xff0c;目前从事全栈工程师工作&#xff0c;刚刚接触 NebulaGraph 不久&#xff0c;还在努力学习当中。图数据库可以高效地表达、存储和分析复杂关系和网络&#xff0c;在特定场景下有着不错的性能。希望通过这篇 nebula-stats-exporter 的…

从0-1实现一个自己的脚手架

当我们在开发的时候&#xff0c;时常会在创建项目的时候重复很多操作&#xff0c;比如下载相同的依赖(锁定依赖版本)、封装网络请求、封装路由、配置代码提示/检查、配置vite/webpack打包、配置自动导入(auto-import)、配置项目基础结构、注册全局指令等&#xff0c;有非常多重…

连锁餐厅降低员工离职率:发誓!绝不是靠“舌尖上的诱惑”

员工社交与成长&#xff0c;企业福利与文化&#xff0c;沃可趣多维度优化员工体验。 连锁餐饮业在全球范围内迅速发展&#xff0c;要为消费者提供更多便利&#xff0c;2023年中国餐饮市场连锁化率达到21%。 然而&#xff0c;这些分散式门店为企业运营创造了挑战。Black Box I…

爬山算法优点

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

前端练习小项目——视觉冲击卡片

前言&#xff1a; 前言&#xff1a;在学习完HTML和CSS之后&#xff0c;我们就可以开始做一些小项目了&#xff0c;本篇文章所讲的小项目为——视觉冲击卡片 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 先让我们看一下效果&a…

美国铁路客运巨头Amtrak泄漏旅客数据,数据销毁 硬盘销毁 文件销毁

旅客的Guest Rewards常旅客积分账户的个人信息被大量窃取。 美国国家客运铁路公司&#xff08;Amtrak&#xff09;近日披露了一起数据泄露事件&#xff0c;旅客的Guest Rewards常旅客积分账户的个人信息被大量窃取。 根据Amtrak向马萨诸塞州提交的泄露通知&#xff0c;5月15日…

微信小程序navigateTo异常(APP-SERVICE-SDK:Unknown URL)

背景 在开发小程序时&#xff0c;可能会用到banner&#xff0c;通过banner跳转至各种子页面。但是因为小程序自身的因素&#xff0c;有些是不允许的&#xff0c;比如通过banner跳转一个http/https链接。如果使用 wx.navigateTo完成跳转时&#xff0c;就会发生异常。 navigate…

HarmonyOS模拟器(phone-x86-api9)一直卡顿的解决方法

在DevEco Studio 3.1.1 Release版本中的Device Manager中创建本地的模拟器&#xff0c;创建phone-x86-api9模拟器成功&#xff0c;但是启动该新建的模拟器一直显示"HarmonyOS"logo图片&#xff0c;然后一直卡在这里&#xff0c;运行结果如下所示&#xff1a; 检查模…

分布式锁三种方案

基于数据库的分布式锁&#xff08;基于主键id和唯一索引&#xff09; 1基于主键实现分布式锁 2基于唯一索引实现分布式锁 其实原理一致&#xff0c;都是采用一个唯一的标识进行判断是否加锁。 原理&#xff1a;通过主键或者唯一索性两者都是唯一的特性&#xff0c;如果多个…