You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

moment.js最近空闲时段查询函数周二查询结果异常

问题:findNearestFreeSlot函数周二查询结果不符合预期

我编写了一个findNearestFreeSlot函数,接收包含day(星期几)和freeSlots('h:mm a'格式时段数组)的对象数组,目标是返回当前时间之后最近的空闲时段,本周无可用时段则返回"wait for next week"。但周二查询时,预期输出应为"Wed, 12:00 pm",实际却返回"Wed, 4:30 pm"。

原函数代码

function findNearestFreeSlot(slotsArray) {
    const currentDate = moment();
    let nearestDayDiff = Infinity;
    let nearestSlot = null;

    for (const daySlots of slotsArray) {
        const { day, freeSlots } = daySlots;

        for (const slot of freeSlots) {
            const slotDateTime = moment(slot, 'h:mm a').day(day);

            // Check if the slot is on or after the current date
            if (slotDateTime.isSameOrAfter(currentDate)) {
                const diffDays = Math.abs(currentDate.diff(slotDateTime, 'days'));

                if (diffDays < nearestDayDiff || (diffDays === nearestDayDiff && slotDateTime.isBefore(nearestSlot))) {
                    nearestDayDiff = diffDays;
                    nearestSlot = slotDateTime;
                }
            }
        }
    }

    return nearestSlot ? nearestSlot.format('ddd, h:mm a') : "wait for next week";
}

测试数组

const freeSlotsArray = [
    {
        day: 'wed',
        freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '3:00 pm', '3:30 pm', '4:30 pm', '5:00 pm', '6:30 pm', '7:00 pm']
    },
    {
        day: 'sat',
        freeSlots: ['7:00 am', '7:30 am', '8:00 am', '9:00 am', '10:00 am', '10:30 am', '11:30 am', '12:00 pm', '12:30 pm']
    },
    {
        day: 'thu',
        freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '4:00 pm', '5:30 pm', '6:30 pm', '7:00 pm']
    },
    {
        day: 'mon',
        freeSlots: ['4:00 pm', '4:30 pm', '6:00 pm', '6:30 pm', '7:30 pm', '8:00 pm', '8:30 pm', '9:30 pm']
    },
];

const nearestFreeSlot = findNearestFreeSlot(freeSlotsArray);
console.log(nearestFreeSlot);

问题分析及修复

问题根源

原函数的核心问题在于使用截断整数的天数差进行比较,无法精确区分同一天内不同时段的远近。Math.abs(currentDate.diff(slotDateTime, 'days'))会将不足一天的时间差截断为0,同时用绝对值处理导致无法准确判断时间先后逻辑。此外,用null初始化nearestSlot会增加比较逻辑的复杂度,容易出现判断失误。

修复后的代码

function findNearestFreeSlot(slotsArray) {
    const now = moment();
    // 初始化一个足够远的未来时间,避免null判断问题
    let nearestSlot = moment().add(100, 'years');

    for (const { day, freeSlots } of slotsArray) {
        // 获取本周该天的起始时间
        const dayStart = moment().day(day).startOf('day');
        // 跳过本周已过去的日期
        if (dayStart.isBefore(now.startOf('day'))) {
            continue;
        }

        for (const slot of freeSlots) {
            // 基于当天起始时间构建slot的完整时间
            const slotTime = moment(dayStart).set({
                hour: moment(slot, 'h:mm a').hour(),
                minute: moment(slot, 'h:mm a').minute()
            });

            // 仅考虑当前时间之后的slot,并更新最近的时段
            if (slotTime.isSameOrAfter(now) && slotTime.isBefore(nearestSlot)) {
                nearestSlot = slotTime;
            }
        }
    }

    // 判断是否找到本周可用时段
    return nearestSlot.isAfter(moment().add(1, 'week')) ? "wait for next week" : nearestSlot.format('ddd, h:mm a');
}

修复说明

  1. 精确时间比较:直接通过isBefore比较moment对象的先后,避免天数差的截断误差。
  2. 明确日期范围:先判断本周的目标日期是否已过,已过则跳过,确保只处理本周未来的时段。
  3. 简化初始化:用远未来时间初始化nearestSlot,无需处理null的特殊情况,逻辑更清晰。
  4. 可靠的时间构建:基于当天起始时间设置时段的小时和分钟,避免moment(slot, 'h:mm a').day(day)可能带来的日期歧义。

内容的提问来源于stack exchange,提问作者Aimal Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:07:33