JavaScript如何将日期数组转换为带累计时长的月份日期范围
实现思路
- 第一步:先把输入的每一条日期字符串解析为包含
Date对象、月份名、年份、日期、小时数的结构化数据,方便后续判断连续性和合并 - 第二步:遍历结构化后的数组,判断相邻两条是否为连续自然日(即下一个日期的时间戳减去当前日期时间戳刚好等于86400000毫秒,也就是1天),同时确认年份、月份相同才合并省略月份
- 第三步:合并连续区间时,累加区间内的小时数,输出格式按要求省略非首条的月份,最终拼接为目标字符串
完整实现代码
const formatDateRanges = (inputArr) => { // 1. 解析输入字符串为结构化数据 const parsedList = inputArr.map(str => { const [month, day, year, hour] = str.split(' ') const date = new Date(`${month} ${day}, ${year}`) return { date, timestamp: date.getTime(), monthName: month, year: Number(year), day: Number(day), hour: Number(hour) } }) const ranges = [] let i = 0 const len = parsedList.length while (i < len) { const current = parsedList[i] let start = current let end = current let totalHour = current.hour // 2. 查找连续日期区间 while (i + 1 < len) { const next = parsedList[i + 1] // 判断是否为连续1天,且同年同月 const isConsecutive = next.timestamp - end.timestamp === 86400000 && next.year === end.year && next.monthName === end.monthName if (!isConsecutive) break end = next totalHour += next.hour i++ } // 3. 拼接区间字符串 let rangeStr if (start.day === end.day) { rangeStr = `${start.monthName} ${start.day} ${start.year} ${totalHour}hrs` } else { rangeStr = `${start.monthName} ${start.day}-${end.day} ${start.year} ${totalHour}hrs` } ranges.push(rangeStr) i++ } // 4. 按要求输出数组格式 return [ranges.join(', ')] }
测试示例
// 示例输入 const input = [ "Nov 23 2021 8 hrs", "Nov 24 2021 8 hrs", "Nov 27 2021 8 hrs", "Dec 3 2021 8 hrs" ] console.log(formatDateRanges(input)) // 输出:["Nov 23-24 2021 16hrs, Nov 27 2021 8hrs, Dec 3 2021 8hrs"]
补充说明
- 代码默认输入的日期数组是按时间升序排列的,如果实际输入可能乱序,可以在解析后加一行
parsedList.sort((a,b) => a.timestamp - b.timestamp)做排序 - 跨月的连续日期不会合并,会按不同月份拆分,符合省略月份仅在同区间同月份生效的逻辑
内容的提问来源于stack exchange,提问作者Logikev
相关产品推荐
相关产品推荐

