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

如何用JavaScript基于已有数据生成可用预约时间段数组

动态生成排除已占用时段的预约可用时间段数组

问题描述

我正在开发毕业设计的预约应用,需要实现一个功能:根据店铺的营业时间、已有的预约记录,动态生成用户可选的预约时间段数组。目前用硬编码全量时段再过滤的方式实现,想找到更灵活、可适配的方案。

需求细节:

  • 店铺包含opens(开门时间)、closes(关门时间)字段,后续需要支持不同店铺的自定义营业时间
  • 每个预约有start和end时间字段,当前默认预约时长30分钟,后续要支持自定义时长
  • 需要生成从开门到关门、间隔对应时长的所有时段,自动排除已被预约占用的时段,最终结果用于用户下拉选择

示例数据:

const shop = {
    user: "fakeid123",
    title: "Barber Shop",
    description: "fake description",
    appointments: [{
            customername: "Kostas",
            start: "12:00",
            end: "12:30"
        },
        {
            customername: "Makis",
            start: "13:00",
            end: "13:30"
        },
        {
            customername: "Kostas",
            start: "14:00",
            end: "14:30"
        },
        {
            customername: "Kostas",
            start: "17:00",
            end: "17:30"
        }
    ],
    opens: "8:00",
    closes: "21:00"
};

解决方案

核心思路

将时间字符串转换为分钟数(如8:00转为480分钟),方便进行数值计算和比较;基于营业时间和预约时长生成所有可能的时段,再过滤掉已被占用的时段,最后转换回时间字符串格式。

实现代码

// 工具函数:将时间字符串(如"8:00")转换为当天的分钟数
function timeToMinutes(timeStr) {
    const [hours, minutes] = timeStr.split(':').map(Number);
    return hours * 60 + minutes;
}

// 工具函数:将分钟数转换回时间字符串(如480转为"8:00")
function minutesToTime(minutes) {
    const hours = Math.floor(minutes / 60);
    const mins = minutes % 60;
    return `${hours}:${mins.toString().padStart(2, '0')}`;
}

// 生成可用预约时段的核心函数
function generateAvailableSlots(shop, appointmentDuration = 30) {
    const opensInMinutes = timeToMinutes(shop.opens);
    const closesInMinutes = timeToMinutes(shop.closes);
    
    // 收集所有已占用时段的起始分钟数(用Set优化查找性能)
    const occupiedStarts = new Set(shop.appointments.map(apt => timeToMinutes(apt.start)));
    
    const availableSlots = [];
    
    // 从开门时间开始,按预约时长步进,生成所有合法时段
    for (let current = opensInMinutes; current + appointmentDuration <= closesInMinutes; current += appointmentDuration) {
        // 若当前时段未被占用,则加入可用列表
        if (!occupiedStarts.has(current)) {
            availableSlots.push({
                start: minutesToTime(current),
                end: minutesToTime(current + appointmentDuration)
            });
        }
    }
    
    return availableSlots;
}

// 使用示例
const availableSlots = generateAvailableSlots(shop);
console.log(availableSlots);

扩展说明

  1. 适配不同预约时长:调用generateAvailableSlots时传入第二个参数即可,例如generateAvailableSlots(shop, 45)会生成45分钟间隔的时段
  2. 适配不同营业时间:只要店铺对象的opens和closes是合法的时间字符串(如"9:30"),函数会自动处理
  3. 性能优化:用Set存储已占用的起始时间,将查找操作的时间复杂度从O(n)降低到O(1),适合预约记录较多的场景

内容的提问来源于stack exchange,提问作者Kwstas Greco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:30:45