Cuente días entre dos fechas con Java 8 mientras ignora ciertos días de la semana

A continuación tengo 3 métodos. El primero es muy simple. Solo cuenta el número total de días. El segundo, sin embargo, no solo contará los días, sino que ignorará los días de la semana que se pasan al método.

Mi problema es que el tercer método no siempre es correcto. Debe coincidir con el segundo método. Supongo que tiene algo que ver con los años bisiestos, porque la diferencia suele ser + = 3 | 4 cuando es incorrecta.

Información adicional

Estoy intentando burlarme de Excelweekday(serial_number,[return_type]) fórmula de alguna manera.

serial_number = startDate:Date - daysOfWeekToInclude:Array<Integer>
Ejemplo
  | A       | B                                                  | C
  +---------+----------------------------------------------------+-----------
1 | Start   | =DATE(2014,9,7)                                    | 9/7/2014                 
2 | End     | =DATE(2025,6,13)                                   | 6/13/2025                    
3 | Include | ={1,2,4,6} (Mon, Tue, Thu, & Sat)                  | <Disp Only>
4 | Days    | =SUM(INT((WEEKDAY($B$1-{1,2,4,6},1)+$B$2-$B$1)/7)) | 2248 

Aquí hay más información sobre esta función:¿Cómo contar / calcular el número de días entre dos fechas en Excel?

Imagen sin procesar

Métodos

Simplemente cuente la cantidad de días entre dos fechas.

public static int simpleDaysBetween(final LocalDate start,
        final LocalDate end) {
    return (int) ChronoUnit.DAYS.between(start, end);
}

Cuente la cantidad de días, ignorando ciertos días de la semana, usando un bucle.

public static int betterDaysBetween(final LocalDate start,
        final LocalDate end, final List<DayOfWeek> ignore) {
    int count = 0;
    LocalDate curr = start.plusDays(0);

    while (curr.isBefore(end)) {
        if (!ignore.contains(curr.getDayOfWeek())) {
            count++;
        }
        curr = curr.plusDays(1); // Increment by a day.
    }

    return count;
}

Cuenta el número de días. de nuevo pero sin bucle.

public static int bestDaysBetween(final LocalDate start,
        final LocalDate end, final List<DayOfWeek> ignore) {
    int days = simpleDaysBetween(start, end);

    if (days == 0) {
        return 0;
    }

    if (!ignore.isEmpty()) {
        int weeks = days / 7;
        int startDay = start.getDayOfWeek().getValue();
        int endDay = end.getDayOfWeek().getValue();
        int diff = weeks * ignore.size();

        for (DayOfWeek day : ignore) {
            int currDay = day.getValue();
            if (startDay <= currDay) {
                diff++;
            }
            if (endDay > currDay) {
                diff++;
            }
        }

        if (endDay > startDay) {
            diff -= endDay - startDay;
        }

        return days - diff;
    }

    return days;
}
Código completo
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;

public class DayCounter {
    public static void main(String[] args) {
        final LocalDate start = LocalDate.of(2014, 9, 7);
        final LocalDate end = LocalDate.of(2025, 6, 13);
        List<DayOfWeek> ignore = Arrays.asList(DayOfWeek.SUNDAY, DayOfWeek.WEDNESDAY, DayOfWeek.FRIDAY);

        print(start);
        print(end);

        System.out.println(simpleDaysBetween(start, end));
        System.out.println(betterDaysBetween(start, end, ignore));
        System.out.println(bestDaysBetween(start, end, ignore));
    }

    public static void print(LocalDate date) {
        System.out.printf("%s -> %s%n", date, date.getDayOfWeek());
    }

    public static int simpleDaysBetween(final LocalDate start,
            final LocalDate end) {
        return (int) ChronoUnit.DAYS.between(start, end);
    }

    public static int betterDaysBetween(final LocalDate start,
            final LocalDate end, final List<DayOfWeek> ignore) {
        int count = 0;
        LocalDate curr = start.plusDays(0);

        while (curr.isBefore(end)) {
            if (!ignore.contains(curr.getDayOfWeek())) {
                count++;
            }
            curr = curr.plusDays(1); // Increment by a day.
        }

        return count;
    }

    public static int bestDaysBetween(final LocalDate start,
            final LocalDate end, final List<DayOfWeek> ignore) {
        int days = simpleDaysBetween(start, end);

        if (days == 0) {
            return 0;
        }

        if (!ignore.isEmpty()) {
            int weeks = days / 7;
            int startDay = start.getDayOfWeek().getValue();
            int endDay = end.getDayOfWeek().getValue();
            int diff = weeks * ignore.size();

            for (DayOfWeek day : ignore) {
                int currDay = day.getValue();
                if (startDay <= currDay) {
                    diff++;
                }
                if (endDay > currDay) {
                    diff++;
                }
            }

            if (endDay > startDay) {
                diff -= endDay - startDay;
            }

            return days - diff;
        }

        return days;
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta