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

如何为MongoDB中的餐厅设计支持跨午夜的营业时间Schema?

解决跨午夜营业时间判断问题

问题分析

原来的逻辑仅处理当日内结束的营业时间(如08:00-20:00),但对于跨午夜的场景(如18:00-次日02:00),存在两个盲区:

  1. 未考虑open时间晚于close时间的情况(如18:00 > 02:00)
  2. 未覆盖次日凌晨时段属于前一天营业周期的情况

解决方案逻辑

需要同时检查当日营业时间和前一天的跨午夜营业时间:

  • 对于当日条目:
    • 若open ≤ close:正常判断当前时间是否在两者之间
    • 若open > close:判断当前时间是否在open到当日23:59之间
  • 对于前一天条目:
    • 若该条目是跨午夜类型(open > close):判断当前时间是否在当日00:00到该条目的close之间

修改后的代码实现

let isOpen = false;
const now = moment();
const currentDay = now.format("dddd").toLowerCase();
const prevDay = now.clone().subtract(1, 'day').format("dddd").toLowerCase();

// 检查当日的营业时间
const todayHours = restaurant.workingHours.find(h => h.day.toLowerCase() === currentDay);
if (todayHours) {
  const open = moment(todayHours.open, "hh:mm");
  const close = moment(todayHours.close, "hh:mm");
  
  if (open.isBefore(close) || open.isSame(close)) {
    // 正常当日营业时段
    if (now.isBetween(open, close, "minute", "[]")) {
      isOpen = true;
    }
  } else {
    // 跨午夜:当日open到23:59
    const endOfDay = now.clone().endOf('day');
    if (now.isBetween(open, endOfDay, "minute", "[]")) {
      isOpen = true;
    }
  }
}

// 若当日未命中,检查前一天的跨午夜时段
if (!isOpen) {
  const prevDayHours = restaurant.workingHours.find(h => h.day.toLowerCase() === prevDay);
  if (prevDayHours) {
    const open = moment(prevDayHours.open, "hh:mm");
    const close = moment(prevDayHours.close, "hh:mm");
    
    if (open.isAfter(close)) {
      // 前一天跨午夜:当日00:00到close
      const startOfDay = now.clone().startOf('day');
      if (now.isBetween(startOfDay, close, "minute", "[]")) {
        isOpen = true;
      }
    }
  }
}

可选Schema优化建议

为了简化时间比较,可以将open和close字段改为当日分钟数(范围0-1439,如08:00=480,02:00=120),这样无需依赖moment的时间对象,直接通过数值比较:

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

// 简化后的判断逻辑
const nowMinutes = now.hours() * 60 + now.minutes();
if (todayHours) {
  const openMin = timeToMinutes(todayHours.open);
  const closeMin = timeToMinutes(todayHours.close);
  
  if (openMin <= closeMin) {
    isOpen = nowMinutes >= openMin && nowMinutes <= closeMin;
  } else {
    isOpen = nowMinutes >= openMin;
  }
}

if (!isOpen && prevDayHours) {
  const openMin = timeToMinutes(prevDayHours.open);
  const closeMin = timeToMinutes(prevDayHours.close);
  
  if (openMin > closeMin) {
    isOpen = nowMinutes <= closeMin;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:50:28