多考勤记录下的休息时长校验与班次工时匹配问题求助
解决多条考勤记录的休息时段计算问题
我明白你现在的痛点——原来的代码只能处理两条考勤记录,没法覆盖员工多次进出的场景。咱们一步步来重构这个逻辑,让它能处理任意数量的考勤记录:
核心思路拆解
- 首先要确保考勤记录是按时间顺序排列的,不然相邻记录的间隔计算会完全出错
- 遍历所有连续的考勤记录对,计算每一段的休息时长(下一条的
ZPZ_Von减去上一条的ZPZ_Bis) - 筛选出时长超过20分钟的休息时段,找出其中最长的那一段
- 对比最长休息时长和班次分配的休息时间,如果实际休息不足,就调整对应记录的时间来补够
修改后的完整代码
private void ResolveLunchPause(Work_schedule selectedShift, List<presence_time> arrivals) { // 先做必要的参数校验,避免空引用或无效数据 if (arrivals == null || arrivals.Count <= 1 || selectedShift == null) return; // 第一步:按到达时间对考勤记录排序,确保时间顺序正确 var sortedArrivals = arrivals.OrderBy(p => p.ZPZ_Von).ToList(); // 第二步:遍历所有相邻记录,计算休息时段并找出最长的有效休息(>20分钟) TimeSpan longestValidBreak = TimeSpan.Zero; int longestBreakIndex = -1; // 记录最长休息时段对应的上一条记录索引 for (int i = 0; i < sortedArrivals.Count - 1; i++) { var currentRecord = sortedArrivals[i]; var nextRecord = sortedArrivals[i + 1]; // 计算当前两段考勤之间的休息时长 TimeSpan breakDuration = nextRecord.ZPZ_Von - currentRecord.ZPZ_Bis; // 只考虑超过20分钟的休息时段,符合需求中的有效休息识别规则 if (breakDuration.TotalMinutes > 20) { // 更新最长休息记录 if (breakDuration > longestValidBreak) { longestValidBreak = breakDuration; longestBreakIndex = i; } } } // 第三步:如果找到有效最长休息,且时长小于班次分配的休息时间,调整对应记录 if (longestBreakIndex != -1 && longestValidBreak.TotalHours < selectedShift.lunch_break) { // 计算需要补充的休息时长 TimeSpan neededBreak = TimeSpan.FromHours(selectedShift.lunch_break) - longestValidBreak; // 调整最长休息时段后的那条记录的到达时间,往后推补够的时长 sortedArrivals[longestBreakIndex + 1].ZPZ_Von = sortedArrivals[longestBreakIndex + 1].ZPZ_Von.Add(neededBreak); // 如果需要把修改后的列表同步回原参数,可取消下面的注释: // arrivals.Clear(); // arrivals.AddRange(sortedArrivals); } }
关键细节说明
- 排序的必要性:数据库返回的记录可能不是按时间顺序存储的,必须先排序才能保证相邻记录是连续的考勤时段
- 有效休息筛选:严格按照需求只计算超过20分钟的休息,排除短暂进出的无效时段
- 精准调整逻辑:只针对最长的有效休息时段进行时间调整,避免影响其他正常的考勤间隔
- 健壮性优化:开头增加了参数校验,避免空引用或数据量不足导致的异常
内容的提问来源于stack exchange,提问作者user9857941
相关产品推荐
相关产品推荐

