java 把一个时间段中的节假日和周末过滤掉,获得一个或多个时间段

本文介绍了一种处理工作时间段内包含节假日的方法,并提供了一个具体的Java实现案例,该方法能够将受节假日影响的时间段拆分为有效的连续工作时段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作中遇到这种需求了,就写了一个方法,测试了几种情况都没有问题

代码中的工具类用的hutool,不能用第三方包的话,可以把工具类的api都换成自己写的计算方法

 /**
     * 处理单个时间段中的节假日
     *
     * @param m 时间段
     * @return 处理过后的一个或多个时间段
     */
    public static List<Map<String, Date>> dispose(Map<String, Date> m, List<String> holidays, List<String> workDays) {
        String ymd = "yyyy-MM-dd";
        Date st = DateUtil.beginOfDay(m.get("st")).toJdkDate();
        Date et = DateUtil.beginOfDay(m.get("et")).toJdkDate();

        if (st == null || et == null) {
            return new ArrayList<>();
        }

        List<Map<String, Date>> result = new ArrayList<>();
        long betweenDay = DateUtil.betweenDay(st, et, true) + 1;
        for (int i = 0; i < betweenDay; i++) {
            if (DateUtil.beginOfDay(st).compareTo(DateUtil.beginOfDay(et)) > 0) {
                break;
            } else if (st.compareTo(et) == 0) {
                String last = DateUtil.format(st, ymd);
                if (workDays.contains(last) || (!holidays.contains(last) && !DateTime.of(st).isWeekend())) {
                    Map<String, Date> map = new HashMap<>();
                    map.put("st", st);
                    map.put("et", et);
                    result.add(map);
                }
                break;
            }

            if (holidays.contains(DateUtil.format(st, ymd))) {
                st = DateUtil.offsetDay(st, 1).toJdkDate();
            } else if (workDays.contains(DateUtil.format(st, ymd))) {
                Date beginT = st;
                Date endT = st;
                long betweenDay1 = DateUtil.betweenDay(st, et, true) + 2;
                for (int j = 0; j < betweenDay1; j++) {
                    st = DateUtil.offsetDay(st, 1).toJdkDate();
                    if (holidays.contains(DateUtil.format(st, ymd))) {
                        Map<String, Date> map = new HashMap<>();
                        map.put("st", beginT);
                        map.put("et", endT);
                        result.add(map);
                        break;
                    } else if (workDays.contains(DateUtil.format(st, ymd))) {
                        if (st.compareTo(et) > 0) {
                            Map<String, Date> map = new HashMap<>();
                            Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
                            map.put("st", beginT);
                            map.put("et", zt);
                            result.add(map);
                            break;
                        }
                        endT = st;
                    } else {
                        if (DateTime.of(st).isWeekend()) {
                            Map<String, Date> map = new HashMap<>();
                            map.put("st", beginT);
                            map.put("et", endT);
                            result.add(map);
                            break;
                        } else {
                            if (st.compareTo(et) > 0) {
                                Map<String, Date> map = new HashMap<>();
                                Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
                                map.put("st", beginT);
                                map.put("et", zt);
                                result.add(map);
                                break;
                            }
                            endT = st;
                        }
                    }
                }
                st = DateUtil.offsetDay(endT, 2).toJdkDate();
            } else {
                if (DateTime.of(st).isWeekend()) {
                    st = DateUtil.offsetDay(st, 1).toJdkDate();
                } else {
                    Date beginT = st;
                    Date endT = st;
                    long betweenDay1 = DateUtil.betweenDay(st, et, true) + 2;
                    for (int j = 0; j < betweenDay1; j++) {
                        st = DateUtil.offsetDay(st, 1).toJdkDate();
                        if (holidays.contains(DateUtil.format(st, ymd))) {
                            Map<String, Date> map = new HashMap<>();
                            map.put("st", beginT);
                            map.put("et", endT);
                            result.add(map);
                            break;
                        } else if (workDays.contains(DateUtil.format(st, ymd))) {
                            if (st.compareTo(et) > 0) {
                                Map<String, Date> map = new HashMap<>();
                                Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
                                map.put("st", beginT);
                                map.put("et", zt);
                                result.add(map);
                                break;
                            }
                            endT = st;
                        } else {
                            if (DateTime.of(st).isWeekend()) {
                                Map<String, Date> map = new HashMap<>();
                                map.put("st", beginT);
                                map.put("et", endT);
                                result.add(map);
                                break;
                            } else {
                                if (st.compareTo(et) > 0) {
                                    Map<String, Date> map = new HashMap<>();
                                    Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
                                    map.put("st", beginT);
                                    map.put("et", zt);
                                    result.add(map);
                                    break;
                                }
                                endT = st;
                            }
                        }


                    }
                    st = DateUtil.offsetDay(endT, 2).toJdkDate();
                }
            }
        }
        return result;
    }

输出结果:

还有一个计算多个时间段中重复天数的方法,有需要可以看这里:java 计算多个时间段中重复的天数

### 关于OA系统中的日期计算方法 在OA系统中,日期计算是一个常见的需求,尤其是在处理诸如请假申请、任务期限设定等功能模块时。对于这些功能而言,精确的日期计算不仅能够提升用户体验,还能确保业务逻辑的准确性。 #### 1. 基本日期运算函数 为了支持复杂的业务逻辑,通常会在后台服务端采用编程语言内置者第三方库来完成基本的加减法操作。例如,在Java环境中可以利用`java.time.LocalDate`类来进行简单的日期增减: ```java LocalDate today = LocalDate.now(); // 加七天后的日期 LocalDate afterSevenDays = today.plusDays(7); System.out.println(afterSevenDays); ``` 这种做法适用于大多数情况下需要动态调整截止日其他重要时间节点的情形[^2]。 #### 2. 工作日排除机制 考虑到实际工作中可能存在节假日不计入工作时间的情况,因此还需要引入额外的工作日历表用于判断特定日期是否属于法定假日周末休息日。当涉及到跨多个部门协调的任务分配时尤为必要。此时可以通过预定义好的节日列表配合算法过滤非工作日,从而得到真正意义上的“下一个工作日”。 ```python from datetime import timedelta, date def next_working_day(d): one_day = timedelta(days=1) while True: d += one_day if d.weekday() < 5 and not is_holiday(d): # Assuming a function `is_holiday()` exists to check holidays. break return d ``` 这种方法能有效地应对因假期而导致的有效工作周期缩短的问题[^4]。 #### 3. 时间区间重叠检测 另外,在某些应用场景下可能还会遇到两个时间段之间是否存在交集的需求,这同样依赖于良好的日期处理能力。比如审核流程里不同层级领导给出意见所需耗费的时间可能会有所差异,这时就需要考虑如何合理安排各环节之间的衔接关系而不至于造成冲突。 ```sql SELECT * FROM leave_requests lr1, leave_requests lr2 WHERE lr1.id != lr2.id AND NOT ( (lr1.start_date > lr2.end_date) OR (lr1.end_date < lr2.start_date) ); -- SQL语句用来找出有重叠的日程条目。 ``` 上述SQL片段展示了怎样通过数据库查询的方式识别出相互覆盖的时间范围,这对于维护有序的企业内部事务至关重要[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿演

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值