javadatetimejodatimesimpledateformatrange-checking

How to determine a date in between Friday and Sunday of the week at a particular time


I'm trying to check a current date and time is in between Friday 17:42 and Sunday 17:42 of the week with Java.

At the moment I'm doing this with really really bad code block. It was a hurry solution. Now I'm refactoring but I couldn't find any method in joda or etc.

Any ideas? Thanks

private final Calendar currentDate = Calendar.getInstance();
private final int day = currentDate.get(Calendar.DAY_OF_WEEK);
private final int hour = currentDate.get(Calendar.HOUR_OF_DAY);
private final int minute = currentDate.get(Calendar.MINUTE);

if (day != 1 && day != 6 && day != 7) {
    if (combined != 0) {
        return badge == 1;
    } else {
        return badge == product;
    }
} else {
    if (day == 6 && hour > 16) {
        if (hour == 17 && minute < 43) {
            if (combined != 0) {
                return badge == 1;
            } else {
                return badge == product;
            }
        } else {
            return badge == 0;
        }
    } else if (day == 6 && hour < 17) {
        if (combined != 0) {
            return badge == 1;
        } else {
            return badge == product;
        }
    } else if (day == 1 && hour > 16) {
        if (hour == 17 && minute < 43) {
            return badge == 0;
        } else {
            if (combined != 0) {
                return badge == 1;
            } else {
                return badge == product;
            }
        }
    } else {
        return badge == 0;
    }
}

I've used the solution like thiswith the help of @MadProgrammer and @Meno Hochschild

Method:

public static boolean isBetween(LocalDateTime check, LocalDateTime startTime, LocalDateTime endTime) {
 return ((check.equals(startTime) || check.isAfter(startTime)) && (check.equals(endTime) || check.isBefore(endTime))); }

Usage:

static LocalDateTime now = LocalDateTime.now();
static LocalDateTime friday = now.with(DayOfWeek.FRIDAY).toLocalDate().atTime(17, 41);
static LocalDateTime sunday = friday.plusDays(2).plusMinutes(1);

if (!isBetween(now, friday, sunday)) { ... }

Thanks again for your efforts.


Solution

  • Date and Calendar have methods that can perform comparisons on other instances of Date/Calendar, equals, before and after

    However, I'd encourage the use of Java 8's new Time API

    public static boolean isBetween(LocalDateTime check, LocalDateTime startTime, LocalDateTime endTime) {
        return ((check.equals(startTime) || check.isAfter(startTime)) && 
                        (check.equals(endTime) || check.isBefore(endTime)));
    }
    

    Which will return true if the supplied LocalDateTime is within the specified range inclusively.

    Something like...

    LocalDateTime start = LocalDateTime.now();
    start = start.withDayOfMonth(26).withHour(17).withMinute(42).withSecond(0).withNano(0);
    LocalDateTime end = start.plusDays(2);
    
    LocalDateTime check = LocalDateTime.now();
    
    System.out.println(check + " is within range = " + isBetween(check, start, end));
    check = start;
    System.out.println(check + " is within range = " + isBetween(check, start, end));
    check = end;
    System.out.println(check + " is within range = " + isBetween(check, start, end));
    check = start.plusDays(1);
    System.out.println(check + " is within range = " + isBetween(check, start, end));
    check = end.plusMinutes(1);
    System.out.println(check + " is within range = " + isBetween(check, start, end));
    

    Which outputs

    2015-06-25T18:31:32.969 is within range = false
    2015-06-26T17:42 is within range = true
    2015-06-28T17:42 is within range = true
    2015-06-27T17:42 is within range = true
    2015-06-28T17:43 is within range = false
    

    Joda-Time has an Interval class which makes it even eaiser

    Interval targetInterval = new Interval(targetStart, targetEnd);
    System.out.println("Contains interval = " + interval.contains(targetInterval)
    

    which is demonstrated here

    A different approach...

    So I was thinking on way home, assuming all you have is the date/time you want to check, how you might determine if the day falls within your range

    LocalDateTime now = LocalDateTime.now();
    boolean isBetween = false;
    switch (now.getDayOfWeek()) {
        case FRIDAY:
        case SATURDAY:
        case SUNDAY:
            LocalDateTime lastFriday = getLastFriday(now);
            LocalDateTime nextSunday = getNextSunday(now);
            isBetween = isBetween(now, lastFriday, nextSunday);
            System.out.println(lastFriday + " - " + nextSunday + ": " + end);
            break;
    }
    

    What this does is checks the dayOfWeek to see if it's within the desired range, if it is, it finds the previous Friday and next Sunday from the specified date and checks to see if it falls between them (see the previous example)

    lastFriday and nextSunday simply adds/subtracts a day from the specified date/time until to reaches the desired dayOfWeek, it then seeds the required time constraints

    public static LocalDateTime getLastFriday(LocalDateTime anchor) {
        LocalDateTime ldt = LocalDateTime.from(anchor);
        return ldt.with(DayOfWeek.FRIDAY).withHour(17).withMinute(42).withSecond(0).withNano(0);
    }
    
    public static LocalDateTime getNextSunday(LocalDateTime anchor) {
        LocalDateTime ldt = LocalDateTime.from(anchor);
        return ldt.with(DayOfWeek.SUNDAY).withHour(17).withMinute(42).withSecond(0).withNano(0);
    }