java 工作日日期计算

public class DateUtil {

    private static SimpleDateFormat hm = new SimpleDateFormat("HH:mm");
    private static SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat ymdhm = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    private static Date lunchBreak = null;
    private static Date workGoOn = null;
    private static Date offDuty = null;
    private static Date startWork = null;
    static {
        try {
            lunchBreak = hm.parse("12:30");
            workGoOn = hm.parse("14:00");
            offDuty = hm.parse("18:30");
            startWork = hm.parse("09:30");
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }


    /**
     * 工作日内时间加法计算
     * @param date
     * @return
     */
    public static Date addInWorkDate(Date date,int hour) throws ParseException {
//        hour = hour * 14;
        //将要加的时间计算出来,需要加几天,每天按照7.5小时计算,超过整数天当成多一天计算
        //先计算天数,如果添加了之后在周末,需要多加两天
        //最后计算小时和分钟是否在工作时段,如果不在,顺延
        //注意,虽然天数已经计算了,超过了也多加了一天,但是如果在哪一天最后的工作时段,多加了一个小时,还是会跨天:解决方法,将计算的时间加上天数剩余的小时,查看是否超过了最后的工作时间,如果超过了,再多加一天
        Double oneDay = 7.5;
        Double days = hour / oneDay;
        Double littleNum = Double.valueOf("0."+days.toString().split("\\.")[1]);
        int intDay = days.intValue();
        Double remainHour = littleNum * oneDay;
        //剩余的小时数转换为分,通过日历计算是否超过了最后的下班时间,如果超过了,天数加1,小时和天分开算
        Integer millSeconds = new Double(remainHour * 60 * 60 * 1000).intValue();
        Date jumpRestday = jumpRestday(date, intDay,millSeconds);
        Date jumpRestTime = jumpRestTime(date, millSeconds);
        Date ret = ymdhm.parse(ymd.format(jumpRestday) + " " + hm.format(jumpRestTime));
        return ret;
    }

    private static String checkAndFixHm(String time) throws ParseException {
        Date parse = hm.parse(time);
        if (parse.before(startWork)) {
            parse = startWork;
        }else if(parse.after(lunchBreak) && parse.before(workGoOn)){
            parse = workGoOn;
        }else if(parse.after(offDuty)){
            parse = startWork;
        }
        return hm.format(parse);
    }

    /**
     * 计算时间
     * 时间校验
     * @param date
     * @param millSeconds
     * @return
     */
    private static Date jumpRestTime(Date date,Integer millSeconds) throws ParseException {
        String dateStr = checkAndFixHm(hm.format(date));
        date = hm.parse(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        /**
         * 当前逻辑是:指定时间在中午以前,直接加,加完判断是否超过了午休时间,如果超过了,在下午上班时间的基础上增加差量
         *
         * 如果当前时间在下班以后,计算当前时间
         *
         *
         * 正确的逻辑是:当前时间如果在中午下班之前,直接加,加完检查是否超过了午休,如果是,计算差量,将差量加到下午上班以后
         *
         * 如果指定时间在下午上班之后,直接加,加完检查是否超过了晚上下班,如果超过了,将差量加到第二天早上上班
         *
         */

        //判断是否跨越了中午,指定的时间如果是在上午,加上时间量超过了午休时间就是跨越了中午,需要把多的时间加到下午去
        if (calendar.getTime().before(lunchBreak) || calendar.getTime().equals(lunchBreak)) {
            calendar.add(Calendar.MILLISECOND,millSeconds);
            Date temp = calendar.getTime();
            if (temp.after(lunchBreak)) {
                Long dif = temp.getTime() - lunchBreak.getTime();
                calendar.setTime(workGoOn);
                calendar.add(Calendar.MILLISECOND,dif.intValue());
                temp = calendar.getTime();
                return temp;
            }
        }else if(calendar.getTime().after(workGoOn) || calendar.getTime().equals(workGoOn)){
            //判断是否跨越了晚上,指定的时间如果超过了下班时间,需要把多余的时间从早上加
            calendar.add(Calendar.MILLISECOND,millSeconds);
            Date temp = calendar.getTime();
            if (temp.after(offDuty)) {
                Long dif = temp.getTime() - offDuty.getTime();
                calendar.setTime(startWork);
                calendar.add(Calendar.MILLISECOND,dif.intValue());
                temp = calendar.getTime();
                return temp;
            }
        }
        Date time = calendar.getTime();
        return time;
    }

    /**
     * 判断时间是否超过了最晚下班时间,如果是,添加一天
     * @return
     */
    private static int judgeIsAddOneDay(Date date,Integer millSeconds) throws ParseException {
        String dateStr = checkAndFixHm(hm.format(date));
        date = hm.parse(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //判断是否跨越了中午,指定的时间如果是在上午,加上时间量超过了午休时间就是跨越了中午,需要把多的时间加到下午去
        if(calendar.getTime().after(workGoOn) || calendar.getTime().equals(workGoOn)){
            //判断是否跨越了晚上,指定的时间如果超过了下班时间,需要把多余的时间从早上加
            calendar.add(Calendar.MILLISECOND,millSeconds);
            Date temp = calendar.getTime();
            if (temp.after(offDuty)) {
                return 1;
            }
        }
        return 0;
    }

    private static Date jumpRestday(Date timeVar,int amount,Integer millSeconds) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(timeVar);
        //判断时间是否过了当天工作时间,如果过了,添加一天
        int i1 = judgeIsAddOneDay(timeVar, millSeconds);
        if (i1 == 1) {

        }
        amount = amount + i1;
        if (hm.parse(hm.format(timeVar)).after(offDuty)) {
            calendar.add(Calendar.DATE,1);
            timeVar = calendar.getTime();
        }
        int i = amount / 5;
        int dif = amount - (i * 5);
//        System.out.println(i+"倍"+(dif > 0 ? "余"+dif : ""));
        int ac = amount;
        if (i != 0) {
            ac = amount + (i * 2);
        }
        //判断余数加上当前时间是否跨越了周末,如果是,再加两天
//        星期六:7,星期天:1
        Calendar instance = Calendar.getInstance();
        instance.clear();
        instance.setTime(timeVar);
        int weekInt = instance.get(Calendar.DAY_OF_WEEK);
        if(weekInt + dif > 6 || weekInt + dif == 1){
            calendar.add(Calendar.DATE,2);
        }
        calendar.add(Calendar.DATE,ac);
        //如果遇到周末,直接加两天
        if (Calendar.SATURDAY == calendar.get(Calendar.DAY_OF_WEEK)) {
            calendar.add(Calendar.DATE,2);
        }else if(Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK)){
            calendar.add(Calendar.DATE,2);
        }
        Date time = calendar.getTime();
        return time;
    }

    public static String formatYmdhm(Date date){
        String format = ymdhm.format(date);
        return format;
    }

}

测试

@Test
    public void testDate() throws ParseException {
        Date date = ymdhm.parse("2018-07-20 20:14");
        Date ret = DateUtil.addInWorkDate(date, 8);
        System.out.println(ret.toLocaleString());
    }

结果

2018-7-24 10:00:00

猜你喜欢

转载自blog.csdn.net/u013958151/article/details/81196631