diff --git a/src/utils/date.js b/src/utils/date.js index ff83a2f..6e9c5ba 100644 --- a/src/utils/date.js +++ b/src/utils/date.js @@ -99,12 +99,30 @@ function getWeeklyOccurrenceIndex(event, dateStr) { // For same week as base start, count from base start to target if (currentBlockStart.getTime() === baseBlockStart.getTime()) { + // Special handling for the first week - only count occurrences on or after base date + if (d.getTime() === baseStart.getTime()) { + return 0 // Base occurrence is always index 0 + } + + if (d < baseStart) { + return null // Dates before base start in same week are not valid occurrences + } + let occurrenceIndex = 0 const cursor = new Date(baseStart) - while (cursor < d) { + + // Count the base occurrence first + if (pattern[cursor.getDay()]) occurrenceIndex++ + + // Move to the next day and count until we reach the target + cursor.setDate(cursor.getDate() + 1) + while (cursor <= d) { if (pattern[cursor.getDay()]) occurrenceIndex++ cursor.setDate(cursor.getDate() + 1) } + + // Subtract 1 because we want the index, not the count + occurrenceIndex-- // Check against repeat count limit if (event.repeatCount !== 'unlimited') { @@ -116,9 +134,23 @@ function getWeeklyOccurrenceIndex(event, dateStr) { } // For different weeks, calculate based on complete intervals - const weekdaysPerInterval = pattern.filter(Boolean).length + // Calculate how many pattern days actually occur in the first week (from base start onward) + let firstWeekPatternDays = 0 + const firstWeekCursor = new Date(baseStart) + const firstWeekEnd = new Date(baseBlockStart) + firstWeekEnd.setDate(firstWeekEnd.getDate() + 6) // End of first week (Sunday) + + while (firstWeekCursor <= firstWeekEnd) { + if (pattern[firstWeekCursor.getDay()]) firstWeekPatternDays++ + firstWeekCursor.setDate(firstWeekCursor.getDate() + 1) + } + + // For subsequent complete intervals, use the full pattern count + const fullWeekdaysPerInterval = pattern.filter(Boolean).length const completeIntervals = blocksDiff / interval - let occurrenceIndex = completeIntervals * weekdaysPerInterval + + // First interval uses actual first week count, remaining intervals use full count + let occurrenceIndex = firstWeekPatternDays + (completeIntervals - 1) * fullWeekdaysPerInterval // Add occurrences from the current week up to the target date const cursor = new Date(currentBlockStart)