根据上下班时间(可能跨1天),利用Excel的公式计算白班时间和夜班时间

本文介绍如何使用Excel公式处理上下班时间,即便时间跨越两天,也能准确计算出白班和夜班的工作时长。适用于需要精细化记录工时的场景,如VBA编程辅助计算。
问题描述:
有每个人的上班时间和下班时间,需要统计白班小时数和夜班小时数 
白班是6:00-22:00 夜班是22:00-第二天6:00。想知道这个表的公式该怎么做? 

 

问题补充:
上班时间可能是这样的:
序号 上班时间  下班时间
1      6:00      17:00
2      5:38      10:00
3      4:20      8:39
4      22:50    5:40
5      18:49    8:38

那如何区分白班和夜班的工时呢??

倒班制的,要是员工5:30去上班 就要为他计算半个小时的夜班
问题分析:
涉及到的几个难点:
1)需要区分白班工时还是夜班工时。
    6:00-22:00 为白班工作时间,与上下班时间段存在多种关系
2)可能跨天工作。因表中存储的只有时间,没有日期,所以存在第一天上班,而第二天才下班的情况
综合起来,可能存在比较复杂的多种情况
解决思路: 
 1)不用VBA编程,用公式实现
 2)直接计算总工时和白班工时,夜班公式通过 总工时-白班工时计算
 3)总工时,只需考虑跨天的情况.只处理最多24小时,也即每个人最多跨1天工作。可简单根据下班时间与上班时间的大小关系处理:当下班时间<上班时间,即认为跨天工作,将下班时间加1后再计算
 4)白班时间:可分为第一天的白班+第二天的白班
     其中:第一天的白班:用 min(白班结束时间,处理后的下班时间)-max(白班开始时间,上
List<PpCalendarDTO> calendarList; 产线日历, 日期还未升序排列 static class PpCalendarDTO { private String dateTime;// 格式如"202511""2025120", 也就是个位数的月份日期没有添0 private String line; } // 换型班次 从排产日历安排时间 else if (PpShiftTypeEnum.换型班次.getCode().equals(order.getShiftType())) { // 不可能一来就换型吧 if (preOrder == null) { System.out.println("不可能一来就换型吧"); continue; } String className = preOrder.getClassName(); Date startTime = preOrder.getStartTime(); Date endTime = preOrder.getEndTime(); Date groupDate = preOrder.getGroupDate(); String line = order.getLine(); BigDecimal totalDemandTime = order.getTotalTime(); // 如果上一条是白班, 且结束时间 } preOrder = order; 如果className 包含"白班" 那么理论上下班时间是groupDate 的晚八点; 如果包含"晚班", 理论下班时间是groupDate 后一日的早八点; 现在要给order设置开始结束时间, 如果preOrder 还没到下班时间也就是endTime 不是下班点, 那么order的开始时间就是endTime; 如果endTime到了下班点, 那么要从产线日历找groupDate 下一条的日期, 并且, 如果className 包含"白班" ,那么本次order的className 就要设置成"晚班", 开始时间也是晚班的开始时间; 这里说一下结束时间: order的结束时间是order的开始时间+totalDemandTime (分钟), 我写了一部分代码, 直接用: // 现在有了 startTime,计算不考虑休息的 endTime endTime = startTime.plus(totalDemandTime); // 考虑休息时间暂停(假设 BREAK_TIMES 是每日固定休息点,如 [12:00, 17:00] 等) for (LocalTime breakTime : BREAK_TIMES) { LocalDate breakDate = startTime.toLocalDate(); // 处理情况(如晚班中的 5:00 休息) if (!startTime.toLocalDate().equals(endTime.toLocalDate()) && breakTime.equals(LocalTime.of(5, 0))) { breakDate = breakDate.plusDays(1); } LocalDateTime breakStart = LocalDateTime.of(breakDate, breakTime); LocalDateTime breakEnd = breakStart.plusMinutes(BREAK_DURATION); // 如果任务时间段与休息时间重叠,则延后结束时间 if (endTime.isAfter(breakStart) && startTime.isBefore(breakEnd)) { long overlapStart = Math.max(startTime.toEpochSecond(ZoneOffset.UTC), breakStart.toEpochSecond(ZoneOffset.UTC)); long overlapEnd = Math.min(endTime.toEpochSecond(ZoneOffset.UTC), breakEnd.toEpochSecond(ZoneOffset.UTC)); if (overlapEnd > overlapStart) { Duration overlap = Duration.ofSeconds(overlapEnd - overlapStart); endTime = endTime.plus(overlap); } } } // 设置最终时间 order.setStartTime(Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant())); order.setEndTime(Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant())); 但是还有一个注意点, 无论上面何种情况, 只要算出order的结束时间超过了下班点, 就要从下班点开始截断, 新建一条order重复操作;
最新发布
10-19
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值