计算两个时间之间的工作时长

计算两个时间之间的工作时长(小时)排除周末

package com.test;


import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Demo1  {

    public static void main(String[] args) throws ParseException {
        String startTime = "2023-01-19 11:00";
        String endTime = "2023-01-22 17:00";
        Date startMoningStart = getDate(startTime,1);
        Date startMoningEnd = getDate(startTime,2);
        Date startAfternoonStart = getDate(startTime,3);
        Date startAfternoonEnd = getDate(startTime,4);
        Date endMoningStart = getDate(endTime,1);
        Date endMoningEnd = getDate(endTime,2);
        Date endAfternoonStart = getDate(endTime,3);
        Date endAfternoonEnd = getDate(endTime,4);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date start = format.parse(startTime);
        Date end = format.parse(endTime);
        int hours = 1000*60*60;
        float result = 0;
        //若开始时间和结束时间是同一天
        SimpleDateFormat simple1 = new SimpleDateFormat("yyyy-MM-dd");
        simple1.format(simple1.parse(startTime)).equals(simple1.format(simple1.parse(endTime)));
        if(simple1.format(simple1.parse(startTime)).equals(simple1.format(simple1.parse(endTime)))){
            //如果结束时间比上班时间早,或者结束时间比开始时间早 或者开始时间晚于下午下班时间,则出差时长为0
            if(end.getTime() <= startMoningStart.getTime() || end.getTime()<=start.getTime() || start.getTime()>=startAfternoonEnd.getTime()
            || isHolidays(startTime)){
                result = 0;
                System.out.println("出差时长为:"+result);
                return;
            }
            //如果结束时间在上午时间段
            if(end.getTime()<=startMoningEnd.getTime()){
                //判断开始时间是否早与上午上班时间
                if(start.getTime()<startMoningStart.getTime()){
                    result = (end.getTime()-startMoningStart.getTime()+0f)/hours;
                }else{
                    result = (end.getTime()-start.getTime()+0f)/hours;
                }
            }
            //如果结束时间在中午时间段
            if(end.getTime()>startMoningEnd.getTime() && end.getTime()<=startAfternoonStart.getTime()){
                //如果开始时间在上午上班之前
                if(start.getTime()<=startMoningStart.getTime()){
                    result = 4;
                }else if(start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()){
                    //开始时间在上午上班时间段
                    result = (startMoningEnd.getTime()-start.getTime()+0f)/hours;
                } else if (start.getTime()>=startMoningStart.getTime()) {
                    //开始时间也在中午
                    result = 0;
                }
            }
            //如果结束时间在下午上班时间段
            if(end.getTime()>startAfternoonStart.getTime() && end.getTime()<=startAfternoonEnd.getTime()){
                if(start.getTime()<=startMoningStart.getTime()){
                    //如果开始时间在上午上班之前
                    result = 4 + (end.getTime()-startAfternoonStart.getTime()+0f)/hours;

                } else if (start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()) {
                    //如果开始时间在上午上班时间
                    result = (startMoningEnd.getTime()-start.getTime() + end.getTime()-startAfternoonStart.getTime()+0f)/hours;

                } else if (start.getTime()>=startMoningEnd.getTime() && start.getTime()<=startAfternoonStart.getTime()) {
                    //开始时间在中午时间段
                    result = (end.getTime() - startAfternoonStart.getTime()+0f)/hours;

                }else if(start.getTime()>startAfternoonStart.getTime()){
                    //开始时间也在下午上班时间段
                    result  = (end.getTime()-start.getTime()+0f)/hours;

                }
            }
            //如果结束时间在下午下班之后
            if(end.getTime() > startAfternoonEnd.getTime()){
                if(start.getTime() <= startMoningStart.getTime()){
                    //如果开始时间在上午上班之前
                    result = 8;

                }else if(start.getTime()>startMoningStart.getTime() && start.getTime()<startMoningEnd.getTime()){
                    //开始时间在上午上班时间段
                    result = 4 + (startMoningEnd.getTime() - start.getTime()+0f)/hours;

                } else if (start.getTime()>=startMoningEnd.getTime() && start.getTime()<=startAfternoonStart.getTime()) {
                    //如果开始时间在中午时间段
                    result = 4;

                } else if (start.getTime()>startAfternoonStart.getTime() && start.getTime()<startAfternoonEnd.getTime()) {
                    //开始时间在下午上班时间段
                    result = (startAfternoonEnd.getTime()-start.getTime()+0f)/hours;

                }
            }

        }else {
            if( end.getTime()<=start.getTime() ){
                result = 0f;
                System.out.println("出差时长为:"+result);
                return;
            }
            //开始时间和结束时间不在同一天
            float startDayHours = getStartDayHours(start,startMoningStart,startMoningEnd,startAfternoonStart,startAfternoonEnd);
            float endDayHours = 8 - getStartDayHours(end,endMoningStart,endMoningEnd,endAfternoonStart,endAfternoonEnd);
            //计算开始时间和结束时间之间隔了几天
            int days = getDays(startTime,endTime);
            float daysHours = (days-1)*8;
            result = daysHours + startDayHours + endDayHours;
            result = deleteHolidays(startTime,endTime,startDayHours,endDayHours,result);

        }

        BigDecimal bigResult  =   new  BigDecimal(result);
        float   finalResult   =  bigResult.setScale(1,  BigDecimal.ROUND_HALF_UP).floatValue();
        System.out.println("出差时长为:"+finalResult);
    }
    //排除出差时长中的节假日时间   这里不考虑休息半天的情况
    // 开始时间startTime 结束时间endTime   开始时间当前的时长startDayHours  结束时间当天的时长endDayHours 排除节假日之前的时长
    //只有startTime 和endTime不在同一天才调用
    private static float deleteHolidays(String startTime,String endTime,float startDayHours,float endDayHours, float hours) throws ParseException {
        float result = hours+0f;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //1判断startTime是否是节假日,周末
        if(isHolidays(startTime)){
            result = result - startDayHours;
        }
        //轮循开始时间到结束时间   当前时间
        String nowDate = startTime;
        do{
            nowDate = format.format(DateUtils.addDays(format.parse(nowDate), 1));
            if(format.format(format.parse(nowDate)).equals(format.format(format.parse(endTime)))){
                break;
            }
            if(isHolidays(nowDate)){
                result = result - 8;
            }
        }while(true);//
        if(isHolidays(endTime)){
           result = result -endDayHours;
        }
        return result;
    }
    //判断一个日期是否是节假日 或者周末
    private static boolean isHolidays(String time) throws ParseException {
        String queryCalenderSql = "";
        //IRowSet query = DbUtil.executeQuery(ctx, queryCalenderSql);
        //    	if(query.next()){
        //    		return true;
        //    	}
        //判断是否是周末
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(format.parse(time));
        if(cal.get(Calendar.DAY_OF_WEEK)==1 || cal.get(Calendar.DAY_OF_WEEK)==7){
            return true;
        }
        return false;
    }

    private static int getDays(String startTime,String endTime) throws ParseException {
        //计算开始和结束时间之间相差的天数
        int result = 0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date start = format.parse(startTime);
        Date end = format.parse(endTime);
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(start);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(end);
        int startDay = calStart.get(Calendar.DAY_OF_YEAR);
        int endDay = calEnd.get(Calendar.DAY_OF_YEAR);
        int yearStart = calStart.get(Calendar.YEAR);
        int yearEnd = calEnd.get(Calendar.YEAR);
        if(yearEnd != yearStart) //不同年
        {
            int timeDistance = 0 ;
            for(int i = yearStart ; i < yearEnd ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0) //闰年
                {
                    timeDistance += 366;
                }
                else //不是闰年
                {
                    timeDistance += 365;
                }
            }
            System.out.println(timeDistance + (endDay-startDay));
            result = timeDistance + (endDay-startDay);

        }
        else //同一年
        {
            result = endDay-startDay;
            System.out.println("判断day2 - day1 : " + (endDay-startDay));
            //return day2-day1;
        }
        return result;
    }
    //计算开始时间那天的出差时长
    private static float getStartDayHours(Date start,Date moningStart,Date moningEnd,Date afternoonStart,Date afternoonEnd){
        float result = 0f;
        //开始时间早与上午上班时间
        if(start.getTime()<=moningStart.getTime()){
            result = 8;
        }else if(start.getTime()>moningStart.getTime() && start.getTime() <moningEnd.getTime()){
            //开始时间在上午时间段
            result = 4 + (moningEnd.getTime()-start.getTime()+0f)/(1000*60*60);
        } else if (start.getTime()>=moningEnd.getTime() && start.getTime()<=afternoonStart.getTime()) {
            //开始时间在中午时间段
            result = 4;
        }else if(start.getTime()>afternoonStart.getTime() && start.getTime()<afternoonEnd.getTime()){
            result = (afternoonEnd.getTime() - start.getTime()+0f)/(1000*60*60);
        }else if(start.getTime()>=afternoonEnd.getTime()){
            result = 0;
        }
        return result;
    }


    //获取给定日期工作时间
    private static Date getDate(String date, int type) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        calendar.setTime(format.parse(date));
        StringBuilder result = new StringBuilder();
        if(calendar.get(Calendar.MONTH)<9){
            result.append(calendar.get(Calendar.YEAR)).append("-0");
        }else{
            result.append(calendar.get(Calendar.YEAR)).append("-");
        }
        result.append(calendar.get(Calendar.MONTH)+1).append("-");
        result.append(calendar.get(Calendar.DATE)).append(" ");
        //1上午开始时间08:30 ;2上午结束时间12:30  3下午开始时间13:00 4下午结束时间17:00
        switch (type){
            case 1:result.append("08:30");
                    break;
            case 2:result.append("12:30");
                    break;
            case 3:result.append("13:00");
                break;
            case 4:result.append("17:00");
                break;
        }
        return format.parse(String.valueOf(result));
    }


}

如果要再排除节假日,可以从数据库中查询,减去节假日的时间就可以了



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值