根据上班时间、周末、节假日计算两个时间之间的工时

需求:计算两个时间之间的工作时间,比如:

计算两个时间的时间差,但是中间有部分时间是要去掉的,比如计算2023-09-10 10:00:00 和 2023-09-15 16:00:00 的时间差,但是要刨除掉17:30~08:30和11:00~13:00的时间,因为这两个时间不是工作时间,同时如果2023-09-10~2023-09-15之间有周末、节假日也要剔除,最终算出来的时长应该是34小时

代码如下:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class TimeWorkingHoursCalculator {


    private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm");
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private LocalTime morningStartTime;
    private LocalTime morningEndTime;
    private LocalTime afternoonStartTime;
    private LocalTime afternoonEndTime;
    private List<LocalDate> specialRestDays ;


    public static void main(String[] args) {
        // 设置工作时间段
        LocalTime morningStartTime = LocalTime.parse("08:30", TIME_FORMAT);
        LocalTime morningEndTime = LocalTime.parse("11:30", TIME_FORMAT);
        LocalTime afternoonStartTime = LocalTime.parse("13:00", TIME_FORMAT);
        LocalTime afternoonEndTime = LocalTime.parse("17:00", TIME_FORMAT);




        // 创建工作时间计算器
        TimeWorkingHoursCalculator calculator = new TimeWorkingHoursCalculator(morningStartTime, morningEndTime,
                afternoonStartTime, afternoonEndTime);

        // 设置特殊休息日
        LocalDate specialRestDay1 = LocalDate.parse("2023-07-01", DATE_FORMAT);
        LocalDate specialRestDay2 = LocalDate.parse("2023-09-12", DATE_FORMAT);
        calculator.addSpecialRestDay(specialRestDay1);
        calculator.addSpecialRestDay(specialRestDay2);

        // 计算工作小时数
        LocalDateTime startTime = LocalDateTime.parse("2023-09-11T10:00", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        LocalDateTime endTime = LocalDateTime.parse("2023-09-15T16:00", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        double workingHours = calculator.calculateWorkingHours(startTime, endTime);

        System.out.println("工作小时数:" + workingHours);
    }



    public TimeWorkingHoursCalculator(LocalTime morningStartTime, LocalTime morningEndTime,
                                  LocalTime afternoonStartTime, LocalTime afternoonEndTime) {
        this.morningStartTime = morningStartTime;
        this.morningEndTime = morningEndTime;
        this.afternoonStartTime = afternoonStartTime;
        this.afternoonEndTime = afternoonEndTime;
        this.specialRestDays = new ArrayList<>();
    }

    public void addSpecialRestDay(LocalDate date) {
        specialRestDays.add(date);
    }

    public double calculateWorkingHours(LocalDateTime startTime, LocalDateTime endTime) {
        double totalHours = 0.0;
        LocalDateTime currentDateTime = startTime;

        while (currentDateTime.isBefore(endTime) || currentDateTime.compareTo(endTime) == 0) {
            LocalDate currentDate = currentDateTime.toLocalDate();

            if (!isWeekend(currentDate) && !isSpecialRestDay(currentDate)) {
                LocalTime currentTime = currentDateTime.toLocalTime();
                boolean isMorningWorkingHour = currentTime.isAfter(morningStartTime)
                        && (currentTime.isBefore(morningEndTime) || currentTime.compareTo(morningEndTime) == 0)
                        && currentDateTime.compareTo(startTime)!=0;//当开始时间为08:30(工作开始时间)时,会导致多出半小时,所以需要增加这个判断
                boolean isAfternoonWorkingHour = currentTime.isAfter(afternoonStartTime)
                        && (currentTime.isBefore(afternoonEndTime) || currentTime.compareTo(afternoonEndTime) == 0 )
                        && currentDateTime.compareTo(startTime)!=0;
//                boolean isMorningWorkingHour = currentTime.isAfter(morningStartTime) 

//                boolean isAfternoonWorkingHour = currentTime.isAfter(afternoonStartTime) && currentTime.isBefore(afternoonEndTime);

                if (isMorningWorkingHour || isAfternoonWorkingHour) {
                    totalHours += 0.5;
                }
            }

            currentDateTime = currentDateTime.plusMinutes(30);//此处设置的步进是30分钟,可以根据自己需求进行调整,但调整的时候需要同步对totalHours的定义、步进进行调整
        }

        return totalHours;
    }

    private boolean isWeekend(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
    }

    private boolean isSpecialRestDay(LocalDate date) {
        return specialRestDays.contains(date);
    }


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值