'Efficiently find ranges of consecutive non-set bits in BitSet

I'm trying to represent calendar available/unavailable slots for a particular day with each bit representing 15mins using BitSet. The bits which are set represent blocked calendar events. For getting the the slots which are free, I need to find the ranges where bits are not set.

I have the following BitSet

00000000000000000011111001000000000011100000000000000000011000

How to efficiently find the ranges of bits which are not set. In this case (1,18) and (24,25) and (27,36) etc.

Below is the current code I have written, which I feel is not efficient and also not clean.

int startIndex = -1;
int nextIndex = -1;
for(int i = getSlotIndex(currentWorkingStartDate); i <= getSlotIndex(currentWorkingEndDate); i++) {
    if(!matrix.get(i)) {
        if(startIndex == -1) {
            startIndex = i;
            nextIndex = i;
        }else {
            nextIndex = i;
        }
    }else if(startIndex != -1){

        ZonedDateTime availableStartDate = day.plusHours((startIndex/4)).plusMinutes(startIndex%4 * 15);
        ZonedDateTime availableEndDate = availableStartDate.plusMinutes((nextIndex - startIndex + 1) * 15L);
        currAvailabilitySlots.addAll(
                getSlotsBasedOnDurationWithTimeZone(new SlotModel(availableStartDate,availableEndDate),durationOfSlot,candidateTimeZoneId));
        startIndex = -1;
        nextIndex = -1;
    }
}

if(startIndex != -1) {
    ZonedDateTime availableStartDate = day.plusHours((startIndex/4)).plusMinutes(startIndex%4 * 15);
    ZonedDateTime availableEndDate = availableStartDate.plusMinutes((nextIndex - startIndex) * 15L);
    currAvailabilitySlots.addAll(
            getSlotsBasedOnDurationWithTimeZone(new SlotModel(availableStartDate,availableEndDate),durationOfSlot,candidateTimeZoneId));
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source