Use Java 8 to calculate the number of days between two dates, while ignoring some days of the week

I have three methods below The first one is simple It only counts the total number of days However, the second not only counts the number of days, but also ignores the day of the week passed to the method

My problem is that the third method is not always correct It should match the second method I guess it's related to leap years, because when it's incorrect, the difference is usually = 3 | 4

Additional information

I tried to simulate Excel's working day (serial_number, [return_type]) formula in some way

serial_number = startDate:Date - daysOfWeekToInclude:Array<Integer>

example

| 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,6},1)+$B$2-$B$1)/7)) | 2248

Here is more information about this function: how to count / calculate the number of days between two dates in excel?

original image

method

>Just calculate the number of days between two dates

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

>Use a cycle to calculate days, ignoring some days of the week

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;
}

>Calculate the number of days Again, but no cycle

public static int bestDaysBetween(final LocalDate start,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;
}

Complete code

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,7);
        final LocalDate end = LocalDate.of(2025,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,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 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 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;
    }
}

Solution

If we talk about the Java 8 API, why not use the Java 8 functionality

static long daysBetween(LocalDate start,LocalDate end,List<DayOfWeek> ignore) {
    return Stream.iterate(start,d->d.plusDays(1))
                 .limit(start.until(end,ChronoUnit.DAYS))
                 .filter(d->!ignore.contains(d.getDayOfWeek()))
                 .count();
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>