Represent your due time as a Duration
:
Duration dueTime = Duration.ofMinutes(15);
Represent your schedule as an EnumMap<DayOfWeek, DailySchedule>
where DailySchedule
is a class that you write for daily opening and closing times. Inside the class represent the times as LocalTime
objects. The class will probably have methods for determining whether a given time of day is before, within or after the schedule interval.
Preferably represent your initial time of 05/05/2020 18:00 as a ZonedDateTime
in the relevant time zone (LocalDateTime
may work too but really isn’t correct for the purpose).
Given your initial date and time, take the day of week out of it. Look up the daily schedule in the map. If the time isn’t within the schedule interval, first adjust it to the start of the interval for either today or tomorrow as appropriate.
First shot at your due date and time is the adjusted date and time plus the due time. ZonedDateTime
has a plus
method that accepts a Duration
. Now if either the due date is on the next date or is after today’s closing time, this is not correct. In this case use Duration.between
for calculating how much time you can take to day (the 10 minutes in your example). Subtract this from the due time (Duration.minus()
). Now proceed from next day’s opening time. The check should really be done in a loop to take into account that the daily schedule might be shorter than the due time. If the schedule for Saturday is 09:00–09:05 and Sunday 10:00–10:05, we may have to cycle from Friday until Monday before we find the right due date and time.
Duration
, DayOfWeek
, LocalTime
and ZonedDateTime
all belong to java.time, the modern Java date and time API. Tutorial link at the bottom.
Later edit: code
I might do it in this way:
Map<DayOfWeek, DailySchedule> weeklySchedule = new EnumMap<>(DayOfWeek.class);
DailySchedule weekdaySchedule
= new DailySchedule(LocalTime.of(7, 30), LocalTime.of(17, 0));
for (DayOfWeek dow = DayOfWeek.MONDAY;
dow.getValue() <= DayOfWeek.FRIDAY.getValue(); dow = dow.plus(1)) {
weeklySchedule.put(dow, weekdaySchedule);
}
weeklySchedule.put(DayOfWeek.SATURDAY,
new DailySchedule(LocalTime.of(9, 0), LocalTime.of(14, 0)));
weeklySchedule.put(DayOfWeek.SUNDAY,
new DailySchedule(LocalTime.of(10, 0), LocalTime.of(13, 0)));
Duration dueTime = Duration.ofMinutes(15);
// Set initial day and time
DayOfWeek currentDay = DayOfWeek.MONDAY;
LocalTime currentTime = LocalTime.of(16, 50);
Duration remainingTimeToAdd = dueTime;
DailySchedule todaysSchedule = weeklySchedule.get(currentDay);
if (todaysSchedule.isBeforeOpen(currentTime)) {
currentTime = todaysSchedule.getOpen();
} else if (todaysSchedule.isOnOrAfterClose(currentTime)) {
currentDay = currentDay.plus(1);
todaysSchedule = weeklySchedule.get(currentDay);
currentTime = todaysSchedule.getOpen();
}
// We will break this loop explicitly when done
while (true) {
// Can time be added today?
LocalTime candidateDueTime = currentTime.plus(remainingTimeToAdd);
if (todaysSchedule.isWithinSchedule(candidateDueTime)) {
// yes, done
currentTime = candidateDueTime;
break;
} else {
// take remainder of today and continue tomorrow
remainingTimeToAdd = remainingTimeToAdd.minus(Duration.between(currentTime, todaysSchedule.getClose()));
currentDay = currentDay.plus(1);
todaysSchedule = weeklySchedule.get(currentDay);
currentTime = todaysSchedule.getOpen();
}
}
System.out.println("Due day and time: " + currentDay + " at " + currentTime);
Output from the example:
Due day and time: TUESDAY at 07:35
The code will not work if the due time is long enough to last from closing on one day to opening the next day. And all sorts of validation and checks are missing, you will want to add them.
Link
Oracle tutorial: Date Time explaining how to use java.time.