Abhitocode commented on code in PR #3788:
URL:
https://github.com/apache/incubator-kie-kogito-runtimes/pull/3788#discussion_r1873660531
##########
jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/timer/BusinessCalendarImpl.java:
##########
@@ -218,244 +164,322 @@ public Date calculateBusinessTimeAsDate(String
timeExpression) {
sec = (mat.group(SIM_SEC) != null) ?
Integer.parseInt(mat.group(SIM_SEC)) : 0;
}
}
+ logger.debug("weeks: {}", hours);
+ logger.debug("days: {}", days);
+ logger.debug("hours: {}", hours);
+ logger.debug("min: {}", min);
+ logger.debug("sec: {}", sec);
int time = 0;
- Calendar c = new GregorianCalendar();
+ Calendar calendar = getCalendar();
+ logger.debug("calendar selected for business calendar: {}",
calendar.getTime());
if (timezone != null) {
- c.setTimeZone(TimeZone.getTimeZone(timezone));
- }
- if (this.clock != null) {
- c.setTimeInMillis(this.clock.getCurrentTime());
+ calendar.setTimeZone(TimeZone.getTimeZone(timezone));
}
// calculate number of weeks
int numberOfWeeks = days / daysPerWeek + weeks;
+ logger.debug("number of weeks: {}", numberOfWeeks);
if (numberOfWeeks > 0) {
- c.add(Calendar.WEEK_OF_YEAR, numberOfWeeks);
+ calendar.add(Calendar.WEEK_OF_YEAR, numberOfWeeks);
}
- handleWeekend(c, hours > 0 || min > 0);
+ logger.debug("calendar WEEK_OF_YEAR: {}",
calendar.get(Calendar.WEEK_OF_YEAR));
+ rollCalendarToNextWorkingDayIfCurrentDayIsNonWorking(calendar,
weekendDays, hours > 0 || min > 0);
hours += (days - (numberOfWeeks * daysPerWeek)) * hoursInDay;
// calculate number of days
int numberOfDays = hours / hoursInDay;
+ logger.debug("numberOfDays: {}", numberOfDays);
if (numberOfDays > 0) {
for (int i = 0; i < numberOfDays; i++) {
- c.add(Calendar.DAY_OF_YEAR, 1);
- handleWeekend(c, false);
- handleHoliday(c, hours > 0 || min > 0);
+ calendar.add(Calendar.DAY_OF_YEAR, 1);
+ boolean resetTime = false;
+ rollCalendarToNextWorkingDayIfCurrentDayIsNonWorking(calendar,
weekendDays, resetTime);
+ logger.debug("calendar after rolling to next working day: {}
when number of days > 0", calendar.getTime());
+ rollCalendarAfterHolidays(calendar, holidays, weekendDays,
hours > 0 || min > 0);
+ logger.debug("calendar after holidays when number of days > 0:
{}", calendar.getTime());
}
}
- int currentCalHour = c.get(Calendar.HOUR_OF_DAY);
- if (currentCalHour >= endHour) {
- c.add(Calendar.DAY_OF_YEAR, 1);
- c.add(Calendar.HOUR_OF_DAY, startHour - currentCalHour);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- } else if (currentCalHour < startHour) {
- c.add(Calendar.HOUR_OF_DAY, startHour - currentCalHour);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- }
+ rollCalendarToWorkingHour(calendar, true);
+ logger.debug("calendar after rolling to working hour: {}",
calendar.getTime());
// calculate remaining hours
time = hours - (numberOfDays * hoursInDay);
- c.add(Calendar.HOUR, time);
- handleWeekend(c, true);
- handleHoliday(c, hours > 0 || min > 0);
-
- currentCalHour = c.get(Calendar.HOUR_OF_DAY);
- if (currentCalHour >= endHour) {
- c.add(Calendar.DAY_OF_YEAR, 1);
- // set hour to the starting one
- c.set(Calendar.HOUR_OF_DAY, startHour);
- c.add(Calendar.HOUR_OF_DAY, currentCalHour - endHour);
- } else if (currentCalHour < startHour) {
- c.add(Calendar.HOUR_OF_DAY, startHour - currentCalHour);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- }
+ calendar.add(Calendar.HOUR, time);
+ logger.debug("calendar after adding time {}: {}", time,
calendar.getTime());
+ boolean resetTime = true;
+ rollCalendarToNextWorkingDayIfCurrentDayIsNonWorking(calendar,
weekendDays, resetTime);
+ logger.debug("calendar after rolling to next working day: {}",
calendar.getTime());
+ rollCalendarAfterHolidays(calendar, holidays, weekendDays, hours > 0
|| min > 0);
+ logger.debug("calendar after holidays: {}", calendar.getTime());
+ rollCalendarToWorkingHour(calendar, true);
+ logger.debug("calendar after rolling to working hour: {}",
calendar.getTime());
// calculate minutes
int numberOfHours = min / 60;
if (numberOfHours > 0) {
- c.add(Calendar.HOUR, numberOfHours);
+ calendar.add(Calendar.HOUR, numberOfHours);
min = min - (numberOfHours * 60);
}
- c.add(Calendar.MINUTE, min);
+ calendar.add(Calendar.MINUTE, min);
// calculate seconds
int numberOfMinutes = sec / 60;
if (numberOfMinutes > 0) {
- c.add(Calendar.MINUTE, numberOfMinutes);
+ calendar.add(Calendar.MINUTE, numberOfMinutes);
sec = sec - (numberOfMinutes * 60);
}
- c.add(Calendar.SECOND, sec);
+ calendar.add(Calendar.SECOND, sec);
+ logger.debug("calendar after adding {} hour, {} minutes and {}
seconds: {}", numberOfHours, numberOfMinutes, sec, calendar.getTime());
+
+ rollCalendarToWorkingHour(calendar, false);
+ logger.debug("calendar after rolling to next working day: {}",
calendar.getTime());
+
+ // take under consideration weekend
+ resetTime = false;
+ rollCalendarToNextWorkingDayIfCurrentDayIsNonWorking(calendar,
weekendDays, resetTime);
+ logger.debug("calendar after rolling to next working day: {}",
calendar.getTime());
+ // take under consideration holidays
+ rollCalendarAfterHolidays(calendar, holidays, weekendDays, resetTime);
+ logger.debug("calendar after holidays: {}", calendar.getTime());
+
+ return calendar.getTime();
+ }
+
+ /**
+ * Indirection used only for testing purposes
+ *
+ * @return
+ */
+ protected Calendar getCalendar() {
+ String debugMessage = testingCalendar != null ? "Returning clone of
testingCalendar " : "Return new GregorianCalendar";
+ logger.debug(debugMessage);
+ return testingCalendar != null ? (Calendar) testingCalendar.clone() :
new GregorianCalendar();
+ }
+
+ /**
+ * Rolls the <code>HOUR_OF_DAY</code> of the given <code>Calendar</code>
depending on
+ * given <code>currentCalHour</code>, instance <code>endHour</code>, and
instance <code>startHour</code>
+ *
+ * It also consider if the startHour < endHour (i.e. working daily hours)
or startHour > endHour (i.e. nightly daily hours).
+ *
+ * The case where startHour = endHour is excluded by validation of the
<code>CalendarBean</code>
+ *
+ * @param toRoll
+ * @param resetMinuteAndSecond if <code>true</code>, reset minutes and
seconds to 0
+ */
+ protected void rollCalendarToWorkingHour(Calendar toRoll, boolean
resetMinuteAndSecond) {
+ logger.debug("toRoll: {}", toRoll.getTime());
+ if (startHour < endHour) {
+ rollCalendarToDailyWorkingHour(toRoll, startHour, endHour);
+ } else {
+ throw new UnsupportedOperationException(String.format("This
feature is not supported yet: %s should be greater than %s", END_HOUR,
START_HOUR));
+ }
+ if (resetMinuteAndSecond) {
+ toRoll.set(Calendar.MINUTE, 0);
+ toRoll.set(Calendar.SECOND, 0);
+ }
+ }
- currentCalHour = c.get(Calendar.HOUR_OF_DAY);
+ /**
+ * Rolls the <code>HOUR_OF_DAY</code> of the given <code>Calendar</code>
to the next "daily" working hour
+ *
+ * @param toRoll
+ * @param startHour
+ * @param endHour
+ */
+ static void rollCalendarToDailyWorkingHour(Calendar toRoll, int startHour,
int endHour) {
+ logger.debug("toRoll: {}", toRoll.getTime());
+ logger.debug("startHour: {}", startHour);
+ logger.debug("endHour: {}", endHour);
+ int currentCalHour = toRoll.get(Calendar.HOUR_OF_DAY);
if (currentCalHour >= endHour) {
- c.add(Calendar.DAY_OF_YEAR, 1);
+ toRoll.add(Calendar.DAY_OF_YEAR, 1);
// set hour to the starting one
- c.set(Calendar.HOUR_OF_DAY, startHour);
- c.add(Calendar.HOUR_OF_DAY, currentCalHour - endHour);
+ toRoll.set(Calendar.HOUR_OF_DAY, startHour);
} else if (currentCalHour < startHour) {
- c.add(Calendar.HOUR_OF_DAY, startHour - currentCalHour);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
+ toRoll.add(Calendar.HOUR_OF_DAY, startHour - currentCalHour);
}
- // take under consideration weekend
- handleWeekend(c, false);
- // take under consideration holidays
- handleHoliday(c, false);
+ logger.debug("calendar after rolling to daily working hour: {}",
toRoll.getTime());
+ }
- return c.getTime();
+ /**
+ * Rolls the <code>HOUR_OF_DAY</code> of the given <code>Calendar</code>
to the next "nightly" working hour
+ *
+ * @param toRoll
+ * @param startHour
+ * @param endHour
+ */
+ static void rollCalendarToNightlyWorkingHour(Calendar toRoll, int
startHour, int endHour) {
+ logger.debug("toRoll: {}", toRoll.getTime());
+ logger.debug("startHour: {}", startHour);
+ logger.debug("endHour: {}", endHour);
+ int currentCalHour = toRoll.get(Calendar.HOUR_OF_DAY);
+ if (currentCalHour < endHour) {
+ toRoll.set(Calendar.HOUR_OF_DAY, endHour);
+ } else if (currentCalHour >= startHour) {
+ toRoll.add(Calendar.DAY_OF_YEAR, 1);
+ toRoll.set(Calendar.HOUR_OF_DAY, endHour);
+ }
+ toRoll.set(Calendar.MINUTE, 0);
+ toRoll.set(Calendar.SECOND, 0);
+ logger.debug("calendar after rolling to nightly working hour: {}",
toRoll.getTime());
}
- protected void handleHoliday(Calendar c, boolean resetTime) {
+ /**
+ * Rolls the given <code>Calendar</code> to the first <b>working day</b>
+ * after configured <code>holidays</code>, if provided.
+ *
+ * Set hour, minute, second and millisecond when
+ * <code>resetTime</code> is <code>true</code>
+ *
+ * @param toRoll
+ * @param holidays
+ * @param resetTime
+ */
+ static void rollCalendarAfterHolidays(Calendar toRoll, List<TimePeriod>
holidays, List<Integer> weekendDays, boolean resetTime) {
+ logger.debug("toRoll: {}", toRoll.getTime());
+ logger.debug("holidays: {}", holidays);
+ logger.debug("weekendDays: {}", weekendDays);
+ logger.debug("resetTime: {}", resetTime);
if (!holidays.isEmpty()) {
- Date current = c.getTime();
+ Date current = toRoll.getTime();
for (TimePeriod holiday : holidays) {
// check each holiday if it overlaps current date and break
after first match
if (current.after(holiday.getFrom()) &&
current.before(holiday.getTo())) {
- Calendar tmp = new GregorianCalendar();
- tmp.setTime(holiday.getTo());
+ Calendar firstWorkingHourTmp = new GregorianCalendar();
+ firstWorkingHourTmp.setTime(holiday.getTo());
- Calendar tmp2 = new GregorianCalendar();
- tmp2.setTime(current);
- tmp2.set(Calendar.HOUR_OF_DAY, 0);
- tmp2.set(Calendar.MINUTE, 0);
- tmp2.set(Calendar.SECOND, 0);
- tmp2.set(Calendar.MILLISECOND, 0);
+ Calendar currentDayTmp = new GregorianCalendar();
+ currentDayTmp.setTime(current);
+ currentDayTmp.set(Calendar.HOUR_OF_DAY, 0);
+ currentDayTmp.set(Calendar.MINUTE, 0);
+ currentDayTmp.set(Calendar.SECOND, 0);
+ currentDayTmp.set(Calendar.MILLISECOND, 0);
- long difference = tmp.getTimeInMillis() -
tmp2.getTimeInMillis();
+ long difference = firstWorkingHourTmp.getTimeInMillis() -
currentDayTmp.getTimeInMillis();
+ int dayDifference = (int) Math.ceil(difference /
(HOUR_IN_MILLIS * 24d));
- c.add(Calendar.HOUR_OF_DAY, (int) (difference /
HOUR_IN_MILLIS));
+ toRoll.add(Calendar.DAY_OF_MONTH, dayDifference);
Review Comment:
okay
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]