java n个工作日后的日期

接到个任务:

       获取到n个工作日后的时间,用于设置截止时间。

处理思路:

判断工作日,这种得弄个节假日表。判断时候,读取数据。

        1,设置节假日。

        2,设置周末补班。

n个工作日,从传的日期开始判断,

        1,先判断如果是节假日。不做处理

        2,判断是否是周末,再判断要不要补班。

        其它都是工作日。工作日不断叠加。

代码:

HolidayUtils

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 *  用于查询间隔n个工作日(包含法定节假日、双休日、调休)后的日期
 *  和查询间隔n个工作日(包含法定节假日、双休日、调休)后的实际间隔的天数
 */
public class HolidayUtils {
    private static final Logger logger = LoggerFactory.getLogger(HolidayUtils.class);
    private static String HOLIDAY = "holiday";
    private static String WORK_WEEKEND_DAY = "workWeekendDay";
    /**
     *  用于判断间隔n个工作日(排除节假日、周六日包含周末补班数据)后的日期
     * @param holidays 节假日数据
     * @param workWeekendDays 周末补班数据
     * @param today  计算开始时间
     * @param invervalWorkDay  间隔工作日
     * @return
     */
    public static Date getIntervalWorkDate(List<String> holidays, List<String> workWeekendDays, Date today, Integer invervalWorkDay) {
        String beginDay = DateUtils.formatDate(today);
        Date tomorrow;
        String tomorrowStr;
        int delay = 1;
        boolean workDay;
        while(delay <= invervalWorkDay){
            //获取明天的日期
            workDay = true;
            tomorrow = DateUtils.addDay(today, NumberUtils.INTEGER_ONE);
            tomorrowStr = DateUtils.formatDate(tomorrow);
            //当前日期+1即tomorrow, 先判断是否是节假日,再判断是否是周末,是周末再判断是否是补班, 直到循环间隔天数------不是节假日不是周末并且不是周末补班
            if (isHoliday(tomorrowStr, holidays)){
                workDay = false;
                logger.info("holiday {}: 是节假日", tomorrowStr);
            } else if(DateUtils.isWeekend(tomorrow)){//是周末,再判断是不是周末补班
                if(!isWorkWeekendDay(tomorrowStr, workWeekendDays)){
                    workDay = false;
                    logger.info("rest day {}: 是周末休息日", tomorrowStr);
                }else {
                    logger.info("work weekend day {}: 是周末调休补班", tomorrowStr);
                }
            } else {
                logger.info("work day {}: 是正常工作日", tomorrowStr);
            }
            if(workDay){ // 工作日,日期加1
                delay++;
            }
            today = tomorrow;
        }
        logger.info("interval date, {} 后{} 个工作日后,日期为:{}",beginDay, invervalWorkDay, DateUtils.formatDate(today));
        return today;
    }


    /**
     * 判断是否是节假日
     */
    public static boolean isHoliday(String dateStr, List<String> holidays) {
        if(!CollectionUtils.isEmpty(holidays)){
            for (String holiday : holidays) {
                if (dateStr.equals(holiday)) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 判断是否是周末补班
     */
    public static boolean isWorkWeekendDay(String dateStr, List<String> workWeekendDays) {
        if(!CollectionUtils.isEmpty(workWeekendDays)){
            for (String workWeekendDay : workWeekendDays) {
                if (dateStr.equals(workWeekendDay)) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     *  获取工作日后的间隔天数
     * @param holidays 节假日数据
     * @param workWeekendDays 周末补班数据
     * @param date 日期
     * @param intervalWorkDay  间隔工作日
     * @return 工作日后的间隔天数
     */
    public static Long getIntervalWorkDay(List<String> holidays, List<String> workWeekendDays, Date date, Integer intervalWorkDay) {
        Date intervalWorkDate = getIntervalWorkDate(holidays, workWeekendDays, date, intervalWorkDay);
        return DateUtils.getDiffDays(date, intervalWorkDate);
    }


    public static void main(String[] args) {
        List<HolidayConfigDTO> holidayDatas = new ArrayList<>();
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-09-29"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-02"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-03"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-04"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-05"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-06"), HOLIDAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-07"), WORK_WEEKEND_DAY));
        holidayDatas.add(new HolidayConfigDTO(DateUtils.parseDate("2023-10-08"), WORK_WEEKEND_DAY));
        // 节假日集合
        List<String> holidays = holidayDatas.stream()
                .filter(holiday -> HOLIDAY.equals(holiday.getType()))
                .map(holiday -> DateUtils.formatDate(holiday.getHoliday())).collect(Collectors.toList());
        // 周末补班日集合
        List<String> workWeekenDays = holidayDatas.stream()
                .filter(workDay -> WORK_WEEKEND_DAY.equals(workDay.getType()))
                .map(workDay -> DateUtils.formatDate(workDay.getHoliday())).collect(Collectors.toList());
        Date createDate = DateUtils.parseDate("2023-09-27");
        Integer intervalWorkDay = 6;
        Date intervalWorkDate = HolidayUtils.getIntervalWorkDate(holidays, workWeekenDays, createDate, intervalWorkDay);
        System.out.println(DateUtils.formatDate(intervalWorkDate));
        Long diffDays = DateUtils.getDiffDays(createDate, intervalWorkDate);
        logger.info("intervalWorkDay {}, realIntervalDay {}", intervalWorkDay, diffDays);


    }


}

DateUtils

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class DateUtils {
    private static String datePattern = "yyyy-MM-dd";
    private static String dateHourPattern = "yyyy-MM-dd HH";
    private static String dateTimePattern = "yyyy-MM-dd HH:mm:ss";
    private static String dateTimePatternSSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
    private static String dateTimeSuffixPattern = "yyyyMMddHHmmss";
    private static String zeroTime = " 00:00:00";
    private static String endTime = " 23:59:59";
    public static String format(Date date, String pattern) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, pattern);
    }
    public static String format(Date date, String pattern, TimeZone timeZone) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, pattern, timeZone);
    }
    public static String formatDate(Date date) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, datePattern);
    }
    public static String formatDate(Date date, TimeZone timeZone) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, datePattern, timeZone);
    }
    public static String formatDateTime(Date date) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, dateTimePattern);
    }
    public static String formatDateTime(Date date, TimeZone timeZone) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, dateTimePattern, timeZone);
    }
    public static Date parseDate(String str) {
        if (StringUtils.isBlank(str))
            return null;
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str, datePattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Date parseDateTime(String str) {
        if (StringUtils.isBlank(str))
            return null;
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str, dateTimePattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Date parseDateTime(String str, String dateTimePattern) {
        if (str == null)
            return null;
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str, Locale.CHINESE, dateTimePattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Date formatDateTimeZero(Date date) {
        String formatDate = formatDate(date);
        return parseDateTime(formatDate + zeroTime);
    }
    public static Date formatDateTimeEnd(Date date) {
        String formatDate = formatDate(date);
        return parseDateTime(formatDate + endTime);
    }
    public static Date getCurDateTime() {
        Date date = new Date();
        String curDate = DateFormatUtils.format(date, dateTimePatternSSSXXX);
        return DateUtils.parseDateTime(curDate, dateTimePatternSSSXXX);
    }


    public static Date getFirstOfHour(Date date) {
        String formatDate = format(date, dateHourPattern);
        return parseDateTime(formatDate + ":00:00");
    }
    public static Date getLastOfHour(Date date) {
        String formatDate = format(date, dateHourPattern);
        return parseDateTime(formatDate + ":59:59");
    }
    public static Date getFirstOfDay(Date date) {
        String formatDate = format(date, datePattern);
        return parseDateTime(formatDate + zeroTime);
    }
    public static Date getLastOfDay(Date date) {
        String formatDate = format(date, datePattern);
        return parseDateTime(formatDate + endTime);
    }
    /**
     * 获取指定日期所在月的第一天
     * @param date 日期
     * @return 所在月的第一天
     */
    public static Date getFirstOfMonth(Date date) {
        //获取当前月第一天:
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        return formatDateTimeZero(calendar.getTime());
    }
    /**
     * 获取指定日期所在月的第最后一天
     * @param date 日期
     * @return  最后一天
     */
    public static Date getLastOfMonth(Date date) {
        //获取当前月最后一天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return formatDateTimeEnd(calendar.getTime());
    }
    /**
     * 获取当年的第一天
     */
    public static Date getCurrentFirstOfYear() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getFirstOfYear(currentYear);
    }
    /**
     * 获取当年的最后一天
     */
    public static Date getCurrentLastOfYear() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getLastOfYear(currentYear);
    }
    /**
     * 获取某年第一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getFirstOfYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }


    /**
     * 获取某年第一天日期
     * @param date 日期
     * @return Date
     */
    public static Date getFirstOfYear(Date date) {
        int year = Integer.parseInt(String.format("%tY", date));
        return formatDateTimeZero(getFirstOfYear(year));
    }
    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getLastOfYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }
    /**
     * 获取某年最后一天日期
     * @param date 日期
     * @return Date
     */
    public static Date getLastOfYear(Date date) {
        int year = Integer.parseInt(String.format("%tY", date));
        return formatDateTimeEnd(getLastOfYear(year));
    }
    /**
     * 计算两个日期之间的时间差,到秒
     * @param start  开始日期
     * @param end    结束日期
     * @return Long
     */
    public static Long getDiffDatesToSec(Date start, Date end) {
        long startTime = start.getTime();
        long endTime = end.getTime();
        return (endTime - startTime) / 1000;
    }
    public static Date addDay(Date start, Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }
    public static Date addMonth(Date start, Integer month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }
    public static Long getRemainMilOneDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Long seconds = (calendar.getTime().getTime() - date.getTime());
        return seconds;
    }
    public static Long getDiffDays(Date start, Date end) {
        Long day = (parseDate(formatDate(end)).getTime() - parseDate(formatDate(start)).getTime())
                / (1000 * 60 * 60 * 24);
        return day;
    }
    public static String getCurrentTimeSuffix() {
        Date now = new Date();
        return format(now, dateTimeSuffixPattern);
    }
    /**
     * 判断是否是周末
     */
    public static boolean isWeekend(Date date) {
        Calendar cal = Calendar.getInstance();
        assert date != null;
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
    } 
    public static void main(String args[]) {
        String format = getCurrentTimeSuffix();
        System.out.println(format);
    }
}

HolidayConfigDTO

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
@Data
@ToString
@ApiModel(value = "节假日配置")
@AllArgsConstructor
public class HolidayConfigDTO {
    @ApiModelProperty(value = "节假日")
    private Date holiday;
    @ApiModelProperty(value = "holiday 节假日, workWeekenDay 周末工作日")
    private String type;
}

数据库配置

DROP TABLE IF EXISTS `holiday_config`;
CREATE TABLE `holiday_config` ( 
  `holiday` date DEFAULT NULL,
  `type` varchar(20) DEFAULT 'holiday' 
    COMMENT 'holiday:法定节假日;workWeekenDay 调休补班' 
) COMMENT='节假日配置表,需要每年根据法定节假日具体时间更新一次';

总结:

        判断n个工作日后,设置一个节假日表。每年维护一次,就很方便了。

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

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

相关文章

(mac)Promethues监控之mysqld_exporter(MySQL监控)

搭建Mysqld_exporterPrometheusGrafana监控系统 普罗米修斯是后端数据监控平台&#xff0c;通过Mysqld_exporter收集mysql数据&#xff0c;Grafana将数据用图形的方式展示出来 前提&#xff1a;已安装grafana和promethues 1.下载安装Mysql &#xff08;1&#xff09;启动MySQL…

回到唐诗宋词的创作现场,与伟大诗词人的灵魂共振

一、教程前言 本套唐诗宋词教程&#xff0c;大小3.15G&#xff0c;1个压缩文件。 二、教程目录 1-读诗&#xff0c;或许可以让我们更加接近自己.mp4 2-漠漠水田飞白鹭——王维的自然世界.mp4 3-不知何处是他乡——李白的酒徒生涯.mp4 4-桃花流水窅然去——李白的轻盈写作…

异步日志方案spdlog

异步日志方案spdlog spdlog 是一款高效的 C 日志库&#xff0c;它以其极高的性能和零成本的抽象而著称。spdlog 支持异步和同步日志记录&#xff0c;提供多种日志级别&#xff0c;并允许用户将日志输出到控制台、文件或自定义的接收器。 多线程使用和同步、异步日志没有关系是…

信号带宽和上升沿时间

我们在抽取高速信号的S参数时避不开的一个环节是设置仿真带宽&#xff0c;经常听到有人讲要设置基频&#xff08;奈奎斯特频率&#xff09;的4倍or 5倍带宽&#xff0c;如果是这样&#xff0c;就有一个问题&#xff1a;如果是56Gbps的NRZ信号&#xff0c;那仿真带宽真要设置到1…

Android Studio 报错:AVD Pixel_3a_API_30_x86 is already running

在我的Android Studio和虚拟机运行时&#xff0c;我的电脑不小心关机了&#xff0c;在启动后再次打开Android Studio并运行虚拟机时发现报错。 Error while waiting for device: AVD Pixel_3a_API_30_x86 is already running. If that is not the case, delete the files at C…

NAT网络地址转换实验(思科)

华为设备参考&#xff1a;NAT网络地址转换实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 NAT&#xff08;Network Address Translation&#xff09;&#xff0c;即网络地址转换技术&#xff0c;是一种在现代计算机网络中广泛应用的技术&#xff0c;主要用于有效管…

Markdown 对勾符号

Markdown中根号符号不完美&#xff0c;少了上面一横&#xff0c;更像对勾&#xff1a;√ 输入&#xff1a; 即可显示为&#xff1a; 在 youtrack 上面的 KB 页面&#xff0c;也适用。 Markdown 对勾符号 - 文档交付 - iSharkFlyMarkdown中根号符号不完美&#xff0c;少了上面一…

配置Trunk

1、实验目的 通过本实验可以掌握&#xff1a; Native VLAN 的含义和配置。IEEE802.1q 封装。Trunk 配置和调试方法。 2、实验拓扑 配置 Trunk 的实验拓扑如下图所示。 3、实验步骤 3.1 在交换机S1、S2上创建 VLAN 并把端口划分到相应的VLAN中 &#xff08;1&#xff09;配…

【网络安全】HTTP协议 — 基础

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 学习目标​ 一、万维网的诞生与发展​编辑 1.万维网的诞生与发展 2.HTTP协议诞生与发展 二、网络基础 1.TCP/IP分层传输 1&#xff09;TCP/IP协议 2&#xff09;封装与拆封 …

初步认识Vscode

4.26初步认识Vscode &#xff08;一&#xff09;快捷键的使用 1. 打开控制端 ctrl ~2. 结束终端 ctrl c3. 多行同时对齐输出 按住shift alt 光标多选4. 多行同时任意位置输出 按住alt 光标单点你想要输入的位置5. 代码太长了&#xff0c;想混行编辑 alt z6. 打开设置控制…

C++ AVL树

文章目录 AVL树的概念AVL树基本框架AVL树的插入AVL树的插入&#xff08;无旋转&#xff09;AVL树的插入&#xff08;旋转操作&#xff09;单旋双旋旋转代码 上面我们知道二叉搜索树在特殊情况下查找的时间复杂度为O(N), 所以为了解决二叉搜索树不稳定的问题&#xff0c;我们引入…

关于OSPF报文学习

目录 一.OSPF学习补充 &#xff08;1&#xff09;OSPF报文头部 &#xff08;2&#xff09;ospf建立邻居关系 1.Hello报文——建立邻居关系 2.hello报文头部 &#xff08;3&#xff09;OSPF建立邻接关系 1.发送DD报文 2.DD报文头部 &#xff08;4&#xff09;关于DR,BD…

深入OceanBase内部机制:分区机制构建高可用、高性能的分布式数据库基石

码到三十五 &#xff1a; 个人主页 在数据库技术的发展历程中&#xff0c;随着数据量的不断增长和业务需求的日益复杂&#xff0c;如何高效地存储、查询和处理数据成为了关键挑战。OceanBase作为一款高性能、高可用的分布式关系数据库&#xff0c;通过其独特的分区机制&#xf…

03 spring-boot+mybatis+jsp 的增删改查的入门级项目

前言 主要是来自于 朋友的需求 项目概况 就是一个 用户信息的增删改查然后 具体到业务这边 使用 mybatis xml 来配置的增删改查 后端这边 springboot mybatis mysql fastjson 的一个基础的增删改查的学习项目, 简单容易上手 前端这边 jsp 的 基础的试题的增删改查 学习项…

Shell脚本学习记录

0.理解Linux文件权限 0.1 Linux安全性 用户的权限是通过创建用户时分配的用户ID(UID)来追踪的&#xff0c;UID是个数值&#xff0c;每个用户都有一个唯一的UID 0.1.1 /etc/passwd文件 Linux系统使用一个专门的文件/etc/passwd来匹配登录名与对应的UID值&#xff0c;该文件包…

本地体验最强开源模型Llama3+Qnw(支持Windows和Mac)

一键运行大模型本地软件&#xff08;含模型&#xff09;&#xff1a;点击下载 Meta放出Llama3模型了&#xff0c;也应该是这段时间里的一个科技大新闻了。 Llama一直都是开源大语言模型的领头羊驼。 而Llama3又是所有羊驼中最新的领头羊。 可以简单地来看一下官方的对比数据…

Open-Sora:开源版的Sora

项目简介 本项目希望通过开源社区的力量复现Sora&#xff0c;由北大-兔展AIGC联合实验室共同发起&#xff0c;当前我们资源有限仅搭建了基础架构&#xff0c;无法进行完整训练&#xff0c;希望通过开源社区逐步增加模块并筹集资源进行训练&#xff0c;当前版本离目标差距巨大&…

FSMC读取FPGA的FIFO

一、硬件说明 FSMC配置 单片机的代码如下&#xff1a; #define VALUE_ADDRESS_AD1 (__IO uint16_t *)0x60400000while (1){if(!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_8)) //数据非空{data *(__IO uint16_t *)VALUE_ADDRESS_AD1;data2 *(__IO uint16_t *)VALUE_ADDRESS_AD1…

C语言:插入排序

插入排序 1.解释2.步骤3.举例分析示例结果分析 1.解释 插入排序是一种简单直观的排序算法&#xff0c;它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。插入排序在实现上&#xff0c;通常采…

Qt中的 tableView 设置 二进制 十六进制 序号表头

二 进制序号 因为QTableView的垂直表头并不支持使用委托来自定义。 相反&#xff0c;可以通过将自定义的QWidget作为QHeaderView的标签来实现这一目标。 代码&#xff1a; #include <QApplication> #include <QMainWindow> #include <QVBoxLayout> #include …
最新文章