使用Moment.js获取过往最近时间、当前班次及时间解析的技术问询
解决Moment.js解析跨天时间及匹配当前工作班次的问题
嘿,我完全懂你的困扰!当当前时间是凌晨04:00时,把字符串“22:00:00”解析成Moment对象后,它默认会绑定到当天的22点,但实际上这个时间应该属于前一天,这直接影响了你判断当前所属工作班次的准确性。下面我来一步步帮你解决这个问题:
第一步:修正跨天时间的解析
首先,我们需要判断解析后的时间与当前时间的先后关系,如果当前时间早于解析的时间(比如04:00 < 22:00),就把解析的时间往前推一天:
// 解析目标时间字符串 const targetTime = moment('22:00:00', 'HH:mm:ss'); // 获取当前时间 const now = moment(); // 如果当前时间早于目标时间,说明目标时间属于前一天 if (now.isBefore(targetTime)) { targetTime.subtract(1, 'day'); } console.log(targetTime.format('YYYY-MM-DD HH:mm:ss')); // 假设当前是2024-05-20 04:00,输出会是2024-05-19 22:00:00
第二步:从数组中匹配当前工作班次
假设你的工作班次数组是这样的(包含跨天的夜班):
const shifts = [ { name: '夜班', start: '22:00:00', end: '06:00:00' }, { name: '白班', start: '06:00:00', end: '14:00:00' }, { name: '中班', start: '14:00:00', end: '22:00:00' } ];
我们可以写一个通用函数来匹配当前班次,自动处理跨天情况:
function getCurrentShift(currentTime, shifts) { // 提取当前时间的时分秒,生成当天的时间对象 const nowTime = moment({ hour: currentTime.hour(), minute: currentTime.minute(), second: currentTime.second() }); return shifts.find(shift => { let shiftStart = moment(shift.start, 'HH:mm:ss'); let shiftEnd = moment(shift.end, 'HH:mm:ss'); // 处理跨天班次:如果结束时间早于开始时间,说明班次跨到了第二天 if (shiftEnd.isBefore(shiftStart)) { shiftEnd.add(1, 'day'); } // 判断当前时间是否在班次范围内 if (shiftEnd.isAfter(shiftStart)) { // 分两种情况:当天的正常班次,或者跨天班次的次日时间段 return nowTime.isBetween(shiftStart, shiftEnd) || (nowTime.isBefore(shiftEnd.clone().subtract(1, 'day')) && nowTime.isAfter(shiftStart)); } return nowTime.isBetween(shiftStart, shiftEnd); }); } // 使用示例:当前时间为04:00 const now = moment('04:00:00', 'HH:mm:ss'); const currentShift = getCurrentShift(now, shifts); console.log(currentShift.name); // 输出:夜班
补充说明
这个函数的核心逻辑是:
- 对于跨天的班次(比如夜班22:00到次日06:00),我们把结束时间加一天,让时间范围变成「当天22:00 → 次日06:00」
- 然后判断当前时间是否落在这个调整后的区间内,这样凌晨4点就能正确匹配到前一天开始的夜班
内容的提问来源于stack exchange,提问作者lingo
相关产品推荐
相关产品推荐

