BulkUpdateUtil { @SuppressWarnings("unchecked") public static JSONObject addSchedulingDates(final Event event, final JSONObject scheduling) { final JSONObject result = deepCopy(scheduling); ZonedDateTime startDate = ZonedDateTime.parse(event.getRecordingStartDate()); ZonedDateTime endDate = ZonedDateTime.parse(event.getRecordingEndDate()); final InternalDuration oldDuration = InternalDuration.of(startDate.toInstant(), endDate.toInstant()); final ZoneId timezone = ZoneId.of((String) result.get("timezone")); if (result.containsKey(SCHEDULING_START_KEY)) { startDate = adjustedSchedulingDate(result, SCHEDULING_START_KEY, startDate, timezone); } if (result.containsKey(SCHEDULING_END_KEY)) { endDate = adjustedSchedulingDate(result, SCHEDULING_END_KEY, endDate, timezone); } if (endDate.isBefore(startDate)) { endDate = endDate.plusDays(1); } if (result.containsKey("duration")) { final JSONObject time = (JSONObject) result.get("duration"); final InternalDuration newDuration = new InternalDuration(oldDuration); if (time.containsKey("hour")) { newDuration.hours = (Long) time.get("hour"); } if (time.containsKey("minute")) { newDuration.minutes = (Long) time.get("minute"); } if (time.containsKey("second")) { newDuration.seconds = (Long) time.get("second"); } if (result.containsKey(SCHEDULING_END_KEY)) { startDate = endDate.minusHours(newDuration.hours) .minusMinutes(newDuration.minutes) .minusSeconds(newDuration.seconds); } else { endDate = startDate.plusHours(newDuration.hours) .plusMinutes(newDuration.minutes) .plusSeconds(newDuration.seconds); } } if (result.containsKey("weekday")) { final String weekdayAbbrev = ((String) result.get("weekday")); if (weekdayAbbrev != null) { final DayOfWeek newWeekDay = Arrays.stream(DayOfWeek.values()) .filter(d -> d.name().startsWith(weekdayAbbrev.toUpperCase())) .findAny() .orElseThrow(() -> new IllegalArgumentException("Cannot parse weekday: " + weekdayAbbrev)); final int daysDiff = newWeekDay.getValue() - startDate.getDayOfWeek().getValue(); startDate = startDate.plusDays(daysDiff); endDate = endDate.plusDays(daysDiff); } } result.put(SCHEDULING_START_KEY, startDate.format(DateTimeFormatter.ISO_INSTANT)); result.put(SCHEDULING_END_KEY, endDate.format(DateTimeFormatter.ISO_INSTANT)); return result; } private  BulkUpdateUtil(); static Optional<Event> getEvent(
    final IndexService indexSvc,
    final AdminUISearchIndex index,
    final String id); @SuppressWarnings("unchecked") static JSONObject addSchedulingDates(final Event event, final JSONObject scheduling); @SuppressWarnings("unchecked") static JSONObject toNonTechnicalMetadataJson(final JSONObject scheduling); @SuppressWarnings("unchecked") static JSONObject mergeMetadataFields(final JSONObject first, final JSONObject second);  }
@Test public void testAddSchedulingDates() { final Event event = EasyMock.mock(Event.class); EasyMock.expect(event.getRecordingStartDate()).andReturn("2018-05-16T13:22:23Z").anyTimes(); EasyMock.expect(event.getRecordingEndDate()).andReturn("2018-05-16T17:12:13Z").anyTimes(); EasyMock.replay(event); testAddSchedulingDates("scheduling1", event); testAddSchedulingDates("scheduling2", event); testAddSchedulingDates("scheduling3", event); testAddSchedulingDates("scheduling4", event); testAddSchedulingDates("scheduling5", event); }