如何用Moment.js拆分带时分秒的日期范围为子时段数组
用Moment.js拆分带时分秒的时间段为按天划分的子时段
我来帮你搞定这个时段拆分的需求,用moment.js完全可以轻松实现,咱们先理清楚核心逻辑,再写代码:
核心拆分逻辑
你的需求本质是把一个跨天的时间段拆成三类子时段:
- 开始当天的部分时段:从给定的
Start时间到当天的23:59:59 - 中间所有完整自然天:每天的
00:00:00到23:59:59 - 结束当天的部分时段:从当天的
00:00:00到给定的End时间
如果开始和结束是同一天,那直接返回包含这一个完整时段的数组就行。
具体实现代码
下面是完整的函数,直接可以用moment.js运行:
function splitTimeRange(startStr, endStr) { const result = []; const start = moment(startStr); const end = moment(endStr); // 情况1:开始和结束是同一天 if (start.isSame(end, 'day')) { result.push({ Start: start.format('YYYY-MM-DD HH:mm:ss'), End: end.format('YYYY-MM-DD HH:mm:ss') }); return result; } // 情况2:跨多天,分三部分处理 // 1. 开始当天的剩余时段 const startDayEnd = start.clone().endOf('day').subtract(1, 'millisecond'); // 转成23:59:59 result.push({ Start: start.format('YYYY-MM-DD HH:mm:ss'), End: startDayEnd.format('YYYY-MM-DD HH:mm:ss') }); // 2. 中间的完整天数 const nextDay = start.clone().add(1, 'day').startOf('day'); const dayBeforeEnd = end.clone().subtract(1, 'day').startOf('day'); // 循环添加中间的每一天 let currentDay = nextDay.clone(); while (currentDay.isSameOrBefore(dayBeforeEnd, 'day')) { const dayEnd = currentDay.clone().endOf('day').subtract(1, 'millisecond'); result.push({ Start: currentDay.format('YYYY-MM-DD HH:mm:ss'), End: dayEnd.format('YYYY-MM-DD HH:mm:ss') }); currentDay.add(1, 'day'); } // 3. 结束当天的时段 result.push({ Start: end.clone().startOf('day').format('YYYY-MM-DD HH:mm:ss'), End: end.format('YYYY-MM-DD HH:mm:ss') }); return result; }
测试你的示例数据
把你给的时间传进去:
const start = '2019-09-06 14:00:00'; const end = '2019-09-09 19:30:00'; const result = splitTimeRange(start, end); console.log(result);
输出结果完全符合你的要求:
[ { Start: '2019-09-06 14:00:00', End: '2019-09-06 23:59:59' }, { Start: '2019-09-07 00:00:00', End: '2019-09-07 23:59:59' }, { Start: '2019-09-08 00:00:00', End: '2019-09-08 23:59:59' }, { Start: '2019-09-09 00:00:00', End: '2019-09-09 19:30:00' } ]
关键细节说明
- 用
moment.clone():避免修改原始的moment对象,因为moment是 mutable 的,直接操作会改变原数据 endOf('day')默认返回的是23:59:59.999,所以用subtract(1, 'millisecond')转成你需要的23:59:59isSame(end, 'day'):精确判断两个时间是否在同一天- 循环中间天数时用
isSameOrBefore:确保不会漏掉结束日期前的最后一天
内容的提问来源于stack exchange,提问作者Giuseppe Lodi Rizzini
相关产品推荐
相关产品推荐

