做到一个请假管理项目,请假的时候选完开始时间和结束时间后需要实时计算请假总时长(工作日时间),在方法中先设置好上午和下午的上班时间和下班时间,我的计算是精确到分钟就够了,具体代码如下
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class LeaveCalculator {
public static double calculateLeaveHours(String startTimeStr, String endTimeStr) {
// 定义工作日的上班时间段
LocalDateTime startOfWorkday = LocalDateTime.of(2000, 1, 1, 8, 30);
LocalDateTime endOfWorkdayMorning = LocalDateTime.of(2000, 1, 1, 11, 20);
LocalDateTime startOfWorkdayAfternoon = LocalDateTime.of(2000, 1, 1, 14, 0);
LocalDateTime endOfWorkday = LocalDateTime.of(2000, 1, 1, 18, 0);
// 定义日期时间格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
// 解析请假开始时间和结束时间
LocalDateTime startTime = LocalDateTime.parse(startTimeStr, formatter);
LocalDateTime endTime = LocalDateTime.parse(endTimeStr, formatter);
// 初始化总请假小时数
double totalLeaveHours = 0.0;
// 计算工作日内的请假时间
LocalDateTime currentDateTime = startTime;
while (currentDateTime.isBefore(endTime) || currentDateTime.isEqual(endTime)) {
// 判断当前时间是否为工作日
if (currentDateTime.getDayOfWeek() != DayOfWeek.SATURDAY && currentDateTime.getDayOfWeek() != DayOfWeek.SUNDAY) {
// 判断当前时间是否在工作日内的上午或下午工作时间段内
if ((currentDateTime.toLocalTime().isAfter(startOfWorkday.toLocalTime()) && currentDateTime.toLocalTime().isBefore(endOfWorkdayMorning.toLocalTime())) ||
(currentDateTime.toLocalTime().isAfter(startOfWorkdayAfternoon.toLocalTime()) && currentDateTime.toLocalTime().isBefore(endOfWorkday.toLocalTime()))) {
// 计算当前时间到下一个上班时间或下班时间的时间差
LocalDateTime nextWorkTime = currentDateTime.plus(1, ChronoUnit.HOURS);
LocalDateTime endOfWorkdayOrEndLeaveTime = nextWorkTime.isAfter(endTime) ? endTime : nextWorkTime;
double hoursToAdd = ChronoUnit.MINUTES.between(currentDateTime, endOfWorkdayOrEndLeaveTime) / 60.0;
totalLeaveHours += hoursToAdd;
currentDateTime = endOfWorkdayOrEndLeaveTime;
} else {
currentDateTime = currentDateTime.plus(1, ChronoUnit.MINUTES);
}
} else {
currentDateTime = currentDateTime.plus(1, ChronoUnit.DAYS).withHour(8).withMinute(30).withSecond(0).withNano(0);
}
}
// 返回总请假小时数,保留两位小数
return Math.round(totalLeaveHours * 100.0) / 100.0;
}
}