首页 > 其他分享 >某一个时间点加天数 跳过双休日 和节假日

某一个时间点加天数 跳过双休日 和节假日

时间:2024-10-28 08:57:56浏览次数:1  
标签:LocalDate BigDecimal get 点加 toString date 双休日 holiday 跳过

0、创建节假日表


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for jsh_holiday
-- ----------------------------
DROP TABLE IF EXISTS `jsh_holiday`;
CREATE TABLE `jsh_holiday`  (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `holiday` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `tenant_id` int NULL DEFAULT NULL,
  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 882 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

1、获取当年所有的国家节假日存在一个表中 通过接口
https://timor.tech/api/holiday/year/2024

public BaseResponseInfo initHolidays() throws UnirestException {
        BaseResponseInfo res = new BaseResponseInfo();
        // ... 添加其他节假日
        HttpResponse response = Unirest.get("https://timor.tech/api/holiday/year/2024")
                .header("X-Access-Token", "af0d9c6e6f3d4e04b79e7c7d5b54c306_63")
                .header("Content-Type", "application/json").asString();
        Object body = response.getBody();
        JSONObject jsonObject = JSONObject.parseObject(body.toString());
        if (jsonObject.get("holiday") != null) {
            JSONObject json = JSON.parseObject(jsonObject.get("holiday").toString());
            for (Map.Entry<String, Object> entry : json.entrySet()) {
                Holiday holiday = new Holiday();
                holiday.setHoliday("2024-" + entry.getKey());
                JSONObject value = JSON.parseObject(entry.getValue().toString());
                holiday.setType(value.get("holiday").toString());
                holidayMapper.insert(holiday);
            }
        }
        res.data = null;
        res.code = 200;
        return res;
    }

2、工具类中封装好一个通用方法 跳过双休及假日的方法

//传入参数跳过及假日
    public static LocalDate calculateEndDate2(LocalDate startDate, int workDays, Map<String, String> holidays) {
        int count = 0;
        LocalDate date = startDate;
        date = date.minusDays(1);

        while (count < workDays) {
            date = date.plusDays(1);
            // 检查是否是周末
            if (date.getDayOfWeek() != DayOfWeek.SATURDAY && date.getDayOfWeek() != DayOfWeek.SUNDAY) {
                // 检查是否是节假日
                String formattedDate = date.toString();

                if (!holidays.containsKey(formattedDate)) {
                    count++;
                }
            } else {
                //遇到周末刚好补办
                String formattedDate = date.toString();
                //是不是周末补办 存在节假日表里面 并且是补办的状态
                if (holidays.containsKey(formattedDate) && !"true".equals(holidays.get(formattedDate))) {
                    count++;
                }
            }
        }
        return date;
    }

3、业务代码

public BaseResponseInfo autoSchedulingEndTime1(@RequestBody JSONObject jsonObject) throws ParseException, UnirestException {
        BaseResponseInfo res = new BaseResponseInfo();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 定义节假日,格式为 "YYYY-MM-DD"
        Map<String, String> holidays = this.getHoliday();

        String startTime = jsonObject.get("startTime").toString(); //开始时间
        BigDecimal quantity = BigDecimal.valueOf(Double.valueOf(jsonObject.get("quantity").toString())); //数量
        BigDecimal beat = BigDecimal.valueOf(Double.valueOf(jsonObject.get("beat").toString()));//节拍
        BigDecimal person = BigDecimal.valueOf(Double.valueOf(jsonObject.get("person").toString()));//人员
        String offferTime = jsonObject.get("offferTime").toString();//交货时间
        Long day = DateUtils.daysBetween(LocalDate.parse(sdf.format(sdf.parse(startTime))), LocalDate.parse(sdf.format(sdf.parse(offferTime)))); //为啥要加1就是他算的差值 是从当天开始的
        // 需要计算的工作日天数
        BigDecimal workDays = BigDecimal.ZERO;
        BigDecimal overtime = BigDecimal.ZERO;

        //数量/节拍/人员 需要的工作天数
        workDays = (quantity.divide(beat, 0, RoundingMode.CEILING).divide(person, 0, RoundingMode.CEILING)).setScale(0, RoundingMode.CEILING); //除不进 向上取整
        //正常需要的工作时长
        overtime = workDays.multiply(new BigDecimal(8)).divide(BigDecimal.valueOf((day + 1)), 2, RoundingMode.HALF_UP); //保留两位小数
        Date parse = sdf.parse(startTime);
        String format_start = sdf.format(parse);
        // 开始日期
        LocalDate startDate = LocalDate.parse(format_start);

        LocalDate endDate = DateUtils.calculateEndDate2(startDate, workDays.intValue(), holidays); //结束时间
        System.out.println("结束日期是: " + endDate);
        JSONObject json = new JSONObject();
        //减去工作时间长都为8小时 为负数的情况下就是说明开始时间和交付时间很充裕 不需要加班
        if (overtime.subtract(new BigDecimal(8)).doubleValue()<0){
            json.put("overtime", "0");  //加班时间
            json.put("totaltime", "8"); //总时长
        }else {
            json.put("overtime", overtime.subtract(new BigDecimal(8)));
            json.put("totaltime", overtime);
        }
        json.put("workTime", "8"); //工作时间
        json.put("endDate", endDate); //结束时间
        res.data = json;
        res.code = 200;
        return res;

    }

4、计算两个时间段差值

 //两个时间段的差值
    public static Long daysBetween(LocalDate startDate, LocalDate endDate) {
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
        return daysBetween;
    }

标签:LocalDate,BigDecimal,get,点加,toString,date,双休日,holiday,跳过
From: https://www.cnblogs.com/pao1pao/p/18509607

相关文章

  • Windows11 24H2系统跳过硬件检测安装
    1、下载Windows11系统镜像访问微软官网地址https://www.microsoft.com/zh-cn/software-download/windows11选择“Windows11(适用于x64设备的多版本ISO)”选项,然后点击下方的“立即下载”按钮,选择“简体中文”选项,然后点击确认会弹出验证创建下载,最后点击“64-bitDownload”按......
  • Nvidia RTX Desktop Manager跳过硬件要求
    相信大家看了上一篇文章,肯定还想继续白*英伟达。所以今天我给大家带来了NvidiaRTXDesktopManager跳过硬件要求的教程。如果要跳过硬件要求的话,还是改NVI文件。由于NVI文件非常多,这里我就不一一介绍怎么删除了。如果感兴趣的朋友可以自己研究。这里我就直接放出懒人包了。......
  • 在K8S中,Worker节点加入集群的全过程?
    在Kubernetes(K8S)中,Worker节点加入集群的全过程涉及多个步骤,包括准备环境、配置网络、生成令牌、执行加入命令以及验证集群状态等。以下是详细的步骤说明:1.准备Worker节点环境检查系统要求:确保Worker节点的操作系统和硬件配置满足Kubernetes的最低要求。检查并安装必要的依......
  • mysql8: 主从复制,从库跳过错误
    一,主从复制,从库报错,因为主库上执行了一条针对从库上不存在数据库的sql 二,解决:1,执行下面的sql即可,stopreplica;SETGLOBALSQL_SLAVE_SKIP_COUNTER=1;startreplica;需要注意以前的stopslave/startslave不可用了2,也可以用下面的sql:MASTER_HOST:主库ip,MASTER_USER:......
  • 想考HCIE,可以直接跳过HCIA和HCIP吗?
    近期,时不时会有一些初涉此领域的新手私下向我咨询:“我渴望一步达成目标,径直考取HCIE,不知是否能够略过HCIA和HCIP呢?”直截了当地给出答案:能够直接报考HCIE,如此一来,确实节省了HCIA和HCIP的考试花费。然而,就学习层面而言,仍旧得如同常规那般从HCIA课程起始进行学习。这个问......
  • 在Delphi中:如何在调试时跳过部分代码?
    在Delphi中调试时,我经常无意地进入我不感兴趣的代码。让我们首先说,我知道您可以使用F8,并且可以使用f4运行到特定的行。示例:functionTMyClass.DoStuff():Integer;begin//dosomestuffbla();end;procedureTMyClass.Foo()beginifDoStuff()=0then//pressF7......
  • Unity跳过闪屏页
    github上一段代码,跳过UnityLogo启动屏:github链接:https://github.com/psygames/UnitySkipSplash/blob/main/SkipSplash.csUnityAPI文档,Unity暴露了SplashScreen.Stop()停止启动屏的API只需要写个静态方法,使用[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.Bef......
  • 安装windows11系统跳过微软账号登录,使用本地账号登录方法
    在安装win11系统,进行到如图下所示界面的时候,暂停下 我们可以按下键盘的Shift+F10按键(部分电脑是Fn+Shift+F10),这时屏幕会出现命令行窗口,如图下所示 我们需要在命令行内输入代码oobe\bypassnro.cmd然后回车,这时候电脑会重启。PS:若无法输入命令,可以电脑插入鼠标点击一下命令行......
  • 尝试将多个列表添加到嵌套字典中,但它跳过第一个列表
    defgetEntries():#Loopvariables,etcloopNum=1setupString=''entryData=[]#Loopwillgothroughallourentryboxesinourgrid#Foreachrow,wewillgetthedataandbuildourstringandthenappenditto......
  • 预装Windows 11系统的新电脑怎么跳过联网验机?这两种方法可以搞定
    温馨提示:跳过windows11联网的方法不一定适用于所有电脑,且过程中可能会出现卡顿的现象,请做好心理准备。验机本就是个人意愿,非硬性要求,不喜欢折腾的就别弄,有问题务必第一时间找售后。不少笔记本新机都预装了Windows11系统,而初次开机的正常流程下,Windows11系统(家庭版......