如何使用Moment.js计算仅纳入营业时间的时间间隔?
用Moment.js计算营业时间内的有效时长
嘿,这个需求我太熟了!要实现只统计营业时间内的时长,核心思路是把跨天的时间段拆分成单个日期的片段,逐个计算每个日期内符合营业时间的分钟数,最后累加总和。咱们一步步来写代码实现:
第一步:定义营业时间规则
先把你的营业时间整理成可复用的配置,方便后续调用:
// 定义营业时间:key是星期几(0=周日,1=周一...6=周六) const businessHours = { // 周一到周五(1-5):8:00 AM - 6:00 PM weekday: { start: { hour: 8, minute: 0 }, end: { hour: 18, minute: 0 } }, // 周六(6)、周日(0):10:00 AM - 2:00 PM weekend: { start: { hour: 10, minute: 0 }, end: { hour: 14, minute: 0 } } };
第二步:写辅助函数获取某天的营业时间
这个函数会根据传入的日期,返回当天营业开始和结束的Moment对象:
function getBusinessHoursForDay(date) { const dayOfWeek = date.day(); // 0=周日,1=周一...6=周六 const isWeekday = dayOfWeek >= 1 && dayOfWeek <= 5; const hours = isWeekday ? businessHours.weekday : businessHours.weekend; // 生成当天营业开始和结束的时间对象 const start = date.clone().startOf('day').set(hours.start); const end = date.clone().startOf('day').set(hours.end); return { start, end }; }
第三步:计算单个日期内的有效时长
这个函数负责计算「某段时间」在「某一天营业时间」内的有效分钟数:
function calculateMinutesInDay(sessionStart, sessionEnd, dayDate) { const { start: businessStart, end: businessEnd } = getBusinessHoursForDay(dayDate); // 确定当天的有效时间段:取session和营业时间的交集 const effectiveStart = moment.max(sessionStart, businessStart); const effectiveEnd = moment.min(sessionEnd, businessEnd); // 如果有效开始时间晚于有效结束时间,说明当天没有重叠,返回0 if (effectiveStart.isAfter(effectiveEnd)) { return 0; } // 计算分钟差 return effectiveEnd.diff(effectiveStart, 'minutes'); }
第四步:主函数——计算跨天的总有效时长
这个函数会把整个时间段拆分成每一天,逐个计算后累加:
function calculateTotalBusinessMinutes(startTime, endTime) { let totalMinutes = 0; const currentDay = startTime.clone().startOf('day'); const endDay = endTime.clone().startOf('day'); // 遍历每一天,从开始日期到结束日期 while (currentDay.isSameOrBefore(endDay)) { // 确定当天的会话时间段:如果是第一天,用startTime;如果是最后一天,用endTime;否则用全天 const dayStart = currentDay.isSame(startTime.startOf('day')) ? startTime : currentDay.clone().startOf('day'); const dayEnd = currentDay.isSame(endDay) ? endTime : currentDay.clone().endOf('day'); // 累加当天的有效分钟数 totalMinutes += calculateMinutesInDay(dayStart, dayEnd, currentDay); // 进入下一天 currentDay.add(1, 'day'); } return totalMinutes; }
验证你的示例
咱们来测试你给的例子:周四4:00 PM开始,周五9:30 AM结束
const taskStart = moment('2024-05-23T16:00:00'); // 周四 const taskEnd = moment('2024-05-24T09:30:00'); // 周五 console.log(calculateTotalBusinessMinutes(taskStart, taskEnd)); // 输出210,完美匹配你的预期!
更复杂的场景测试
比如任务从周六13:00开始,到周一09:00结束:
const complexStart = moment('2024-05-25T13:00:00'); // 周六 const complexEnd = moment('2024-05-27T09:00:00'); // 周一 console.log(calculateTotalBusinessMinutes(complexStart, complexEnd)); // 计算过程:周六13:00-14:00(60分钟)+ 周日10:00-14:00(240分钟)+ 周一08:00-09:00(60分钟)= 360分钟
注意事项
- 确保你已经引入了Moment.js(
moment对象可用) - 如果需要处理时区,可以在创建Moment对象时指定时区(比如使用
moment.tz(...),需要额外引入moment-timezone插件) - 所有边界情况都已处理:比如时间段完全在营业时间外(返回0)、开始/结束刚好在营业起止点、跨多个周末的情况
内容的提问来源于stack exchange,提问作者Gideon Sylvan
相关产品推荐
相关产品推荐

