如何计算同项目不同起止日期匹配员工的共同工作天数?
解决方案
核心计算逻辑
两个员工在同一项目的共同工作时长,本质是求他们工作时间段的重叠区间长度,步骤如下:
- 分别获取两个员工的工作时间段:员工A的
[startA, endA],员工B的[startB, endB] - 重叠区间的起始日期:取两个开始日期中较晚的那个(
max(startA, startB)) - 重叠区间的结束日期:取两个结束日期中较早的那个(
min(endA, endB)) - 若起始日期 ≤ 结束日期,说明存在重叠,用结束日期减去起始日期得到时长;否则无重叠,时长为0
修改后的代码实现
将原代码中projectData.forEach及相关逻辑替换为以下内容,同时优化数据查询效率:
import dayjs from 'dayjs'; // ... 保留原有组件的state、parseFile、onDrop等逻辑不变 const { getRootProps, getInputProps } = useDropzone({ onDrop }); // 用useEffect监听csvData变化,避免重复计算 useEffect(() => { if (!csvData) return; // 构建员工信息映射,避免重复遍历CSV数据 const employeeMap = new Map<string, { start: dayjs.Dayjs; end: dayjs.Dayjs }>(); csvData.forEach(el => { const empId = el[0]; employeeMap.set(empId, { start: dayjs(el[2]), end: dayjs(el[3]) }); }); // 按项目分组员工 const projectData = new Map<string, string[]>(); csvData.forEach(el => { const projectId = el[1]; const empId = el[0]; if (projectData.has(projectId)) { projectData.get(projectId)?.push(empId); } else { projectData.set(projectId, [empId]); } }); // 计算每个项目中员工的共同工作时长 projectData.forEach((employeeIds, projectId) => { if (employeeIds.length === 2) { const [emp1Id, emp2Id] = employeeIds; const emp1 = employeeMap.get(emp1Id)!; const emp2 = employeeMap.get(emp2Id)!; // 计算重叠区间 const overlapStart = dayjs.max(emp1.start, emp2.start); const overlapEnd = dayjs.min(emp1.end, emp2.end); // 计算天数差,无重叠时返回0 const overlapDays = overlapEnd.isAfter(overlapStart) ? overlapEnd.diff(overlapStart, 'day') : 0; console.log(`项目${projectId}中,员工${emp1Id}与${emp2Id}的共同工作时长:${overlapDays}天`); } }); }, [csvData]); // ... 保留原有return部分不变
关键优化点
- 新增
employeeMap缓存员工信息,避免每次查找日期都遍历整个CSV数据,提升性能 - 修复原代码中依赖遍历顺序获取日期的错误逻辑,确保日期匹配准确
- 增加无重叠场景的判断,避免出现负数时长的异常情况
内容的提问来源于stack exchange,提问作者Baleandor
相关产品推荐
相关产品推荐

