React可用时段生成函数问题:时段重叠校验逻辑有误
Hey there! I see the issue with your current function—right now you're only checking if the start of a slot overlaps with an existing appointment, but you're not accounting for the full duration of the service. Let's fix that so we generate slots where the entire service window (start time + service duration) doesn't conflict with any booked appointments.
The Core Problem
Your OverlapsScheduledAppointment function only checks if the slot's start time falls within an existing appointment. But we need to verify if any part of the service window (from slot start to slot start + duration) overlaps with any existing booking.
The correct way to check for overlapping time intervals is:
Two intervals [A_start, A_end] and [B_start, B_end] overlap if
A_start < B_end AND A_end > B_start
Updated Code Solution
Here's the revised function with proper overlap checks, plus some quality-of-life improvements:
const GenerateAvailableTimeSlots = (start, serviceObject, allAppointments) => { const moment = extendMoment(Moment); const config = { slotInterval: 15, startTime: '8:00', endTime: '20:00' }; // Filter appointments for the target day, convert to moment objects (avoids repeated parsing) const filterDailyAppointments = (allAppointments, targetDate) => { const dateStr = targetDate.format('MMMM Do YYYY'); return allAppointments .filter(appt => appt.date === dateStr) .map(appt => ({ start: moment(appt.start.format('HH:mm'), 'HH:mm'), end: moment(appt.end.format('HH:mm'), 'HH:mm') })); }; const dailyAppointments = filterDailyAppointments(allAppointments, start); const businessStart = moment(config.startTime, 'HH:mm'); const businessEnd = moment(config.endTime, 'HH:mm'); // Create a moment duration object for the service length const serviceDuration = moment.duration({ hours: serviceObject.hours, minutes: serviceObject.minutes }); const availableSlots = []; let currentSlot = businessStart.clone(); while (currentSlot.isBefore(businessEnd)) { const slotEnd = currentSlot.clone().add(serviceDuration); // Skip slots where the service would run past business closing time if (slotEnd.isAfter(businessEnd)) { currentSlot.add(config.slotInterval, 'minutes'); continue; } // Check if this slot's full window overlaps with any appointment const hasOverlap = dailyAppointments.some(appt => { return currentSlot.isBefore(appt.end) && slotEnd.isAfter(appt.start); }); if (!hasOverlap) { availableSlots.push(currentSlot.format('HH:mm')); } currentSlot.add(config.slotInterval, 'minutes'); } return availableSlots; };
Key Improvements
- Proper Overlap Detection: Now we validate that the entire service window (start to start + duration) doesn't conflict with existing bookings.
- Business End Time Check: We skip any slot where the service can't finish before closing hours—no more invalid, incomplete bookings.
- Cleaner Date Handling: Appointments are converted to moment objects once, reducing redundant parsing and potential errors.
- Readable Naming: Variables like
configanddailyAppointmentsreplace vague names likex, making the code easier to maintain.
Bonus Edge Case Tips
- The logic correctly allows back-to-back bookings (e.g., an appointment ends at 10:00, a 15-minute service can start at 10:00) because
currentSlot.isBefore(appt.end)returns false for exact matches. - Test with these scenarios to ensure robustness:
- Service duration exactly fits between two appointments
- Service duration is longer than the gap between bookings
- Slot starts right when business opens
- Slot ends right when business closes
内容的提问来源于stack exchange,提问作者imkeVr

