如何为MongoDB中的餐厅设计支持跨午夜的营业时间Schema?
解决跨午夜营业时间判断问题
问题分析
原来的逻辑仅处理当日内结束的营业时间(如08:00-20:00),但对于跨午夜的场景(如18:00-次日02:00),存在两个盲区:
- 未考虑
open时间晚于close时间的情况(如18:00 > 02:00) - 未覆盖次日凌晨时段属于前一天营业周期的情况
解决方案逻辑
需要同时检查当日营业时间和前一天的跨午夜营业时间:
- 对于当日条目:
- 若
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
相关产品推荐
相关产品推荐

