本文主要是介绍计算工作日的工时数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
计算上班工作日的工时数
最近公司要求去计算工时数:
公司上班情况:
1.早上8:30 到 下午的 17:30 , 中午午休时间 12:00 - 13:00 午休一个小时
2.只计算周一到周五,上班的时间,周六日工时数去除
3.午休的一个小时不包含在工作数中
4.设计到跨天计算,比如计算2024-08-27 9:00 到 2024-8-29 17:00
针对以上这种情况,提供如下方法来解决
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;public class WorkHourCalculator {// 更新后的工作时间和午休时间private static final LocalTime WORK_START = LocalTime.of(8, 30);private static final LocalTime WORK_END = LocalTime.of(17, 30);private static final LocalTime BREAK_START = LocalTime.of(12, 0);private static final LocalTime BREAK_END = LocalTime.of(13, 0);public static void main(String[] args) {// 示例:计算从2024-08-29 12:30到2024-08-30 13:30的工时LocalDateTime startTime = LocalDateTime.of(2024, 8, 29, 12, 30);LocalDateTime endTime = LocalDateTime.of(2024, 8, 30, 13, 30);long workMinutes = calculateWorkMinutes(startTime, endTime);System.out.println("Total Work Hours: " + workMinutes / 60.0); // 将分钟转换为小时并显示}public static long calculateWorkMinutes(LocalDateTime startTime, LocalDateTime endTime) {// 跨天情况if (startTime.toLocalDate().isBefore(endTime.toLocalDate())) {return calculateCrossDayWorkMinutes(startTime, endTime);} else {// 同一天的情况return calculateSingleDayWorkMinutes(startTime, endTime);}}private static long calculateCrossDayWorkMinutes(LocalDateTime startTime, LocalDateTime endTime) {LocalDateTime endOfFirstDay = LocalDateTime.of(startTime.toLocalDate(), WORK_END);LocalDateTime startOfSecondDay = LocalDateTime.of(endTime.toLocalDate(), WORK_START);long firstDayWorkMinutes = calculateSingleDayWorkMinutes(startTime, endOfFirstDay);long secondDayWorkMinutes = calculateSingleDayWorkMinutes(startOfSecondDay, endTime);// 中间的完整工作天数,排除周末long fullDays = ChronoUnit.DAYS.between(startTime.toLocalDate().plusDays(1), endTime.toLocalDate());long workDayCount = 0;for (int i = 0; i < fullDays; i++) {LocalDateTime tempDate = startTime.plusDays(i + 1);if (isWorkDay(tempDate)) {workDayCount++;}}// 计算中间完整工作日的工时(按分钟计算)long fullDayWorkMinutes = calculateSingleDayWorkMinutes(WORK_START.atDate(startTime.toLocalDate()), WORK_END.atDate(startTime.toLocalDate()));return firstDayWorkMinutes + secondDayWorkMinutes + (workDayCount * fullDayWorkMinutes);}private static long calculateSingleDayWorkMinutes(LocalDateTime startTime, LocalDateTime endTime) {// 如果是周末,返回0工时if (!isWorkDay(startTime) || !isWorkDay(endTime)) {return 0;}// 限制时间范围在工作时间内LocalTime start = startTime.toLocalTime().isBefore(WORK_START) ? WORK_START : startTime.toLocalTime();LocalTime end = endTime.toLocalTime().isAfter(WORK_END) ? WORK_END : endTime.toLocalTime();Duration workDuration = Duration.between(start, end);// 如果工作时间和午休时间重叠,减去午休时间if (start.isBefore(BREAK_END) && end.isAfter(BREAK_START)) {LocalTime breakStart = BREAK_START.isBefore(start) ? start : BREAK_START;LocalTime breakEnd = BREAK_END.isAfter(end) ? end : BREAK_END;// 只有在工作时间与午休时间重叠的情况下才减去午休时间if (breakStart.isBefore(breakEnd)) {Duration breakDuration = Duration.between(breakStart, breakEnd);workDuration = workDuration.minus(breakDuration);}}return workDuration.toMinutes();}// 判断是否是工作日(周一到周五)private static boolean isWorkDay(LocalDateTime dateTime) {DayOfWeek dayOfWeek = dateTime.getDayOfWeek();return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;}
}
工时按分钟计算:
修改后的方法 calculateWorkMinutes 计算总工时的分钟数,避免了之前只按小时计算而导致的精度问题。跨天工作时间的计算:第一天从 12:30 到 17:30:
总共 5 小时(300 分钟),减去午休时间 30 分钟,所以第一天的工时是 270 分钟。
第二天从 08:30 到 13:30:
08:30 到 12:00 是 3.5 小时(210 分钟),13:00 到 13:30 是 0.5 小时(30 分钟),合计为 240 分钟。
总计为 270 + 240 = 510 分钟,即 8.5 小时。
这篇关于计算工作日的工时数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!