计算日期时间差:获取当前时间距给定日程数组中最近日程的剩余天时分
问题排查
- 星期映射不匹配:JavaScript内置
getDay()方法返回值规则为0=周日、1=周一、…、6=周六,但你的业务定义是1=周一、7=周日,两者基准不统一导致日期计算偏移。 - 日程生效时间逻辑缺陷:
- 每日生效(-1)的日程,当前代码直接映射为当天星期,若当天对应时间已过,不会自动跳到下一天,会返回已过期的时间点。
- 固定星期的日程,若当天对应时间已过,当前代码不会自动跳到下一周的同星期时间,同样会返回过期时间。
- 时间解析逻辑错误:传入的时间是
HH:MM格式的字符串,直接用time[0]/time[1]取到的是单个字符(比如19:00取到的是1和9),需要先按:分割字符串再提取小时、分钟。 - 日程数组语法错误:你定义的
events用了对象大括号{}包裹,内部是无键的数组元素,属于语法错误,应该改为数组中括号[]。
修复实现方案
首先修正日程数组的语法:
let events = [ ["-1 19:00"], ["-1 20:00"], ["-1 17:00", "-1 23:00"], ["1 18:00"], ["2 18:00"], ["3 18:00"], ["4 18:00"], ["5 18:00"], ["6 18:00"], ["7 18:00"], ];
然后实现完整的最近日程计算逻辑:
// 计算单个日程的最近触发时间 function getTargetTime(eventStr) { const [dayStr, timeStr] = eventStr.split(' '); let businessDay = parseInt(dayStr); const [hour, minute] = timeStr.split(':').map(Number); const now = new Date(); // 业务星期转JS标准星期:业务7=周日→JS 0,业务1-6=周一到周六→对应JS 1-6 let jsTargetDay; if (businessDay === -1) { // 每日生效的日程,先默认取今天 jsTargetDay = now.getDay(); } else { jsTargetDay = businessDay === 7 ? 0 : businessDay; } // 计算日期偏移 const todayJsDay = now.getDay(); let dayOffset = jsTargetDay - todayJsDay; if (dayOffset < 0) dayOffset +=7; // 生成目标时间 let target = new Date(now.getTime() + dayOffset * 24 * 60 * 60 * 1000); target.setHours(hour, minute, 0, 0); // 处理时间已过的情况 if (target < now) { if (businessDay === -1) { // 每日日程直接加1天 target = new Date(target.getTime() + 24 * 60 * 60 * 1000); } else { // 固定星期日程加7天 target = new Date(target.getTime() + 7 * 24 * 60 * 60 * 1000); } } return target; } // 计算最近日程的剩余时间 function getNearestEventLeft() { const now = new Date(); let minDiff = Infinity; // 遍历所有日程找到最近的 events.forEach(eventGroup => { eventGroup.forEach(eventStr => { const target = getTargetTime(eventStr); const diff = target - now; if (diff < minDiff) { minDiff = diff; } }) }) // 转换为天/时/分 const days = Math.floor(minDiff / (24 * 60 * 60 * 1000)); const remainingAfterDays = minDiff % (24 * 60 * 60 * 1000); const hours = Math.floor(remainingAfterDays / (60 * 60 * 1000)); const remainingAfterHours = remainingAfterDays % (60 * 60 * 1000); const minutes = Math.floor(remainingAfterHours / (60 * 1000)); return { days, hours, minutes }; } // 调用示例 console.log(getNearestEventLeft());
内容的提问来源于stack exchange,提问作者daysling
相关产品推荐
相关产品推荐

