0

Example

Due time is 15min

Schedule

Mon - Fri: 7:30 - 17:00

Sat 9:00 - 14:00

Sun 10:00 - 13:00

If my initial date(IniDate) is Monday at 6:00 the due date is going to be Monday at 7:45 and if my IniDate is Monday at 8:00 my due date is going to be Monday at 8:15 but if my IniDate is Monday at 16:50 my due date is going to be Tuesday at 7:35 because I had 10 minutes from Monday and 5 minutes from the next day, also if my IniDate is Monday at 18:00 my due date is going to be Tuesday at 7:45, working in Java in Talend Open Studio for data integration, this is going to use actual dates, meaning that lets say my IniDate was 05/05/2020 18:00 then my due date is going to be 06/05/2020 7:45, taking in consideration the schedule, this is my first question, trying to use it in tMap component in the variable section in the middle.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
  • Date libraries... – Mahmoud Hossam May 05 '20 at 21:34
  • 2
    I guess you could just use the [Java data](https://docs.oracle.com/javase/tutorial/datetime/iso/date.html) classes and calculate the due date? Can you post a [mcve] showing what you're struggling with? – Robert May 05 '20 at 21:34

1 Answers1

0

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.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161