钉钉考勤统计工时的方法

发布时间:2024年01月23日

提供一个快捷计算考勤时间的方法,nice!

记得画图很重要,看坐标!


import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalTime;

public class Test {

    public double calculateWorkHours(LocalTime startTime, LocalTime endTime, LocalTime morningStart, LocalTime morningEnd, LocalTime afternoonStart, LocalTime afternoonEnd) {
        // 如果结束时间在开始时间之前,表示跨天,需要调整为第二天的时间
        if (endTime.isBefore(startTime)) {
//            endTime = endTime.plusDays(1);
        }

        // 计算在上下班打卡时间内的时间段
        LocalTime workStart = startTime.isBefore(morningStart) ? morningStart : startTime;
        LocalTime workEnd = endTime.isAfter(afternoonEnd) ? afternoonEnd : endTime;

        // 如果工作开始时间在下午上班时间之后,或者工作结束时间在早上上班时间之前,表示不在上下班打卡时间内
        if (workStart.isAfter(afternoonEnd) || workEnd.isBefore(morningStart)) {
            return 0.0; // 不在上下班打卡时间内,返回0小时
        }

        // 减去上午上班打卡前的时间
        if (workStart.isBefore(morningStart)) {
            Duration beforeMorningStart = Duration.between(workStart, morningStart);
            workStart = morningStart;
            workEnd = workEnd.minus(beforeMorningStart);
        }

        // 减去下午下班打卡后的时间
        if (workEnd.isAfter(afternoonEnd)) {
            Duration afterAfternoonEnd = Duration.between(afternoonEnd, workEnd);
            workEnd = afternoonEnd;
            workStart = workStart.plus(afterAfternoonEnd);
        }

        // 计算在上下班打卡时间内的总时长
        Duration duration = Duration.between(workStart, workEnd);

        // 去掉休息时间 工作早上开始前-下午结束之间  减去中间的值
        if (workStart.isBefore(morningEnd) && workEnd.isAfter(afternoonStart)) {//success 8h
            Duration morningRest = Duration.between(morningEnd, afternoonStart);
            duration = duration.minus(morningRest);
//            if (workStart.isBefore(morningStart)) {
//                duration = duration.minus(Duration.between(workStart, morningStart));
//            }
//            if (workEnd.isAfter(afternoonEnd)) {
//                duration = duration.minus(Duration.between(afternoonEnd, workEnd));
//            }
        }

        // 去掉休息时间  中午某段时间是多余的
//        workStart.isBefore(morningStart) &&
        if (workEnd.isBefore(afternoonStart) && workEnd.isAfter(morningEnd)) {
            Duration morningRest = Duration.between(morningEnd, workEnd);
            duration = duration.minus(morningRest);//前半部分已经自动取
//            if (workStart.isBefore(morningStart)) {
//                duration = duration.minus(Duration.between(workStart, morningStart));
//            }
//            if (workEnd.isAfter(afternoonEnd)) {
//                duration = duration.minus(Duration.between(afternoonEnd, workEnd));
//            }
        }
//        if (workStart.isBefore(afternoonStart) && workStart.isAfter(morningEnd)){
//            Duration morningRest = Duration.between(morningEnd, afternoonStart);
//            duration = duration.minus(morningRest);
//        }
        if (workStart.isBefore(afternoonStart) && workStart.isAfter(morningEnd)) {
            Duration morningRest = Duration.between(workStart, afternoonStart);
            duration = duration.minus(morningRest);
        }

        // 将时长转换为小时数,保留一位小数
        double hours = duration.toMinutes() / 60.0;
        BigDecimal bg = new BigDecimal(hours);
        double f1 = bg.setScale(2, BigDecimal.ROUND_DOWN).doubleValue();//BigDecimal.ROUND_HALF_UP 四舍五入
        //return Math.max(0.0, Math.round(hours * 10.0) / 10.0); // 保留一位小数,确保不返回负数
        return f1; // 保留两位小数,确保不返回负数
    }

    public static void main(String[] args) {
        Test attendanceService = new Test();
//        LocalTime startTime = LocalTime.of(5, 50);
//        LocalTime endTime = LocalTime.of(17, 30); //8h 正确

//        LocalTime startTime = LocalTime.of(11, 10);
//        LocalTime endTime = LocalTime.of(14, 40); //2h 正确

//        LocalTime startTime = LocalTime.of(12, 59);
//        LocalTime endTime = LocalTime.of(17, 31);// 3.83 小时 错误


//        LocalTime startTime = LocalTime.of(6, 10);
//        LocalTime endTime = LocalTime.of(13, 10);//4.16 =250/6
        //--------------
        LocalTime startTime = LocalTime.of(6, 10);
        LocalTime endTime = LocalTime.of(18, 12);


        LocalTime morningStart = LocalTime.of(8, 0);
        LocalTime morningEnd = LocalTime.of(12, 10);

        LocalTime afternoonStart = LocalTime.of(13, 40);
        LocalTime afternoonEnd = LocalTime.of(17, 30);

        double totalWorkHours = attendanceService.calculateWorkHours(startTime, endTime, morningStart, morningEnd, afternoonStart, afternoonEnd);
        System.out.println("在上下班打卡时间内的日志记录小时数: " + totalWorkHours + " 小时");
    }
}



有更好的方法请分享一下哈,我目前只想到这样的方法,只针对白班使用,大家有没有包括夜班的也能使用的方法推荐一下。

文章来源:https://blog.csdn.net/qq_43075645/article/details/135759499
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。