需求:计算两个时间之间的工作时间,比如:
计算两个时间的时间差,但是中间有部分时间是要去掉的,比如计算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
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);
- }
-
-
- }