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

如何优化date-fns取餐时段生成函数以适配营业时间规则?

优化预点餐应用的取餐时段生成函数

需求背景

开发预点餐应用时,取餐时间需满足以下规则:

  • 按指定分钟间隔(如20分钟)生成可选时段
  • 仅在商家营业时段内生成:午市12:00-14:00、晚市16:30-21:30
  • 周日商家不开放午市,其余日期正常开放午市和晚市

现有代码使用date-fns实现基础功能,但硬编码结束时间,需优化适配上述规则,且希望单次生成所有时段并标记可用性,而非分两次生成午/晚市数组。

优化后的实现代码

import { addMinutes, set, getDay, isWithinInterval, format } from "date-fns";

// 抽离营业时段配置,周日(0)单独处理
const BUSINESS_HOURS = {
  default: [
    { start: { hours: 12, minutes: 0 }, end: { hours: 14, minutes: 0 } }, // 午市
    { start: { hours: 16, minutes: 30 }, end: { hours: 21, minutes: 30 } } // 晚市
  ],
  sunday: [
    { start: { hours: 16, minutes: 30 }, end: { hours: 21, minutes: 30 } } // 仅晚市
  ]
};

const generateAvailableTimeSlots = (slotSizeInMinutes: number) => {
  const now = new Date();
  const dayOfWeek = getDay(now); // 0=周日,1-6=周一至周六
  const todayBusinessHours = dayOfWeek === 0 ? BUSINESS_HOURS.sunday : BUSINESS_HOURS.default;

  // 计算当前时间之后的第一个有效间隔时段
  let firstAvailableSlot = now;
  const minutesSinceHour = now.getMinutes();
  const remainder = minutesSinceHour % slotSizeInMinutes;
  if (remainder !== 0) {
    firstAvailableSlot = addMinutes(now, slotSizeInMinutes - remainder);
  } else {
    // 若当前刚好是间隔点,需往后推一个时段避免选择"现在"
    firstAvailableSlot = addMinutes(firstAvailableSlot, slotSizeInMinutes);
  }

  // 获取当天营业结束时间
  const lastBusinessPeriod = todayBusinessHours[todayBusinessHours.length - 1];
  const endOfBusinessDay = set(now, lastBusinessPeriod.end);

  const timeSlots = [];
  let currentSlot = firstAvailableSlot;

  while (currentSlot <= endOfBusinessDay) {
    // 判断当前时段是否落在任意营业区间内
    const isAvailable = todayBusinessHours.some(period => {
      const businessStart = set(now, period.start);
      const businessEnd = set(now, period.end);
      return isWithinInterval(currentSlot, { start: businessStart, end: businessEnd });
    });

    timeSlots.push({
      timestamp: currentSlot,
      displayText: format(currentSlot, "HH:mm"),
      isAvailable
    });

    currentSlot = addMinutes(currentSlot, slotSizeInMinutes);
  }

  return timeSlots;
};

export default generateAvailableTimeSlots;

关键优化说明

  • 配置化营业规则:把不同日期的营业时段抽成可配置对象,后续修改营业时间无需改动核心逻辑
  • 单次循环生成所有时段:从最早可预约时间到营业结束时间,逐个生成时段并同步判断可用性,避免分两次处理午/晚市
  • 周日特殊逻辑自动适配:通过getDay获取星期数,自动切换周日的营业时段配置
  • 可用性标记清晰:每个时段对象包含isAvailable字段,前端可直接根据该字段控制下拉框的可选状态(比如灰置不可用选项)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:15:53