Search code examples
javajava-11localdatetime

Clean way to check if a LocalDateTime is in a given range (working hours of some business)


I need to check if a given LocalDateTime is during the opening hours of a business, which are

Monday - Friday, 8:00 - 12:30 and 14:00 - 18:00

Saturday, 8:00 - 14:00

I have the below method to do so, but I find it too cumbersome for such a simple requirement. Is there an eleganter way to make it cleaner and more readable? May be using some Java 8 lambda magic :-) ?

static boolean duringWorkingHours(LocalDateTime dateTime){
    //MO - FR 08:00 - 12:30
    //MO - FR 14:00 - 18:00
    //SA      08:00 - 14:00

    LocalDateTime morningStart   = dateTime.with(LocalTime.of(8,0));
    LocalDateTime morningEnd     = dateTime.with(LocalTime.of(12,30));
    LocalDateTime afternoonStart = dateTime.with(LocalTime.of(14,0));
    LocalDateTime afternoonEnd   = dateTime.with(LocalTime.of(18,0));

    LocalDateTime saturdayStart  = dateTime.with(LocalTime.of(8,0));
    LocalDateTime saturdayEnd    = dateTime.with(LocalTime.of(14,0));

    Set<DayOfWeek> weekDays      = Set.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY,DayOfWeek.FRIDAY);

    boolean isWeekDay       = weekDays.contains(dateTime.getDayOfWeek());
    boolean isSaturday      = dateTime.getDayOfWeek() == DayOfWeek.SATURDAY;

    boolean isMorning       = (dateTime.isEqual(morningStart) || dateTime.isEqual(morningEnd))
            || (dateTime.isAfter(morningStart) && dateTime.isBefore(morningEnd));

    boolean isAfternoon     = (dateTime.isEqual(afternoonStart) || dateTime.isEqual(afternoonEnd))
            || (dateTime.isAfter(afternoonStart) && dateTime.isBefore(afternoonEnd));

    boolean isSaturdayRange = (dateTime.isEqual(saturdayStart) || dateTime.isEqual(saturdayEnd))
            || (dateTime.isAfter(saturdayStart) && dateTime.isBefore(saturdayEnd));

    return (isWeekDay && isMorning) || (isWeekDay && isAfternoon) || (isSaturday && isSaturdayRange);
}

Solution

  • How about a little helper to make the comparisons easier:

    private static <C extends Comparable<? super C>> boolean isBetween(C value, C start, C end) {
        return value.compareTo(start) >= 0 && value.compareTo(end) < 0;
    }
    
    static boolean duringWorkingHours(LocalDateTime dateTime) {
        LocalTime time = dateTime.toLocalTime();
    
        switch (dateTime.getDayOfWeek()) {
            case SUNDAY:
                return false;
            case SATURDAY:
                return isBetween(time, LocalTime.parse("08:00"), LocalTime.parse("14:00"));
            default:
                return isBetween(time, LocalTime.parse("08:00"), LocalTime.parse("12:30"))
                    || isBetween(time, LocalTime.parse("14:00"), LocalTime.parse("18:00"));
        }
    }