TimeWindowFunctions { public static Supplier<Boolean> isInTimeWindowPredicate(TitusRuntime titusRuntime, TimeWindow timeWindow) { if (isEmpty(timeWindow)) { return () -> true; } List<Function<DayOfWeek, Boolean>> dayPredicates = new ArrayList<>(); timeWindow.getDays().forEach(day -> dayPredicates.add(buildDayPredicate(day))); List<Function<Integer, Boolean>> hourPredicates = new ArrayList<>(); timeWindow.getHourlyTimeWindows().forEach(h -> hourPredicates.add(buildHourlyTimeWindows(h))); Function<DayOfWeek, Boolean> combinedDayPredicate = dayPredicates.isEmpty() ? day -> true : oneOf(dayPredicates); Function<Integer, Boolean> combinedHourPredicate = hourPredicates.isEmpty() ? hour -> true : oneOf(hourPredicates); ZoneId zoneId; try { zoneId = DateTimeExt.toZoneId(timeWindow.getTimeZone()); } catch (Exception e) { titusRuntime.getCodeInvariants().unexpectedError("Unrecognized time zone (data not properly validated)", e); return () -> false; } return () -> { ZonedDateTime dateTime = Instant.ofEpochMilli(titusRuntime.getClock().wallTime()).atZone(zoneId); return combinedDayPredicate.apply(dateTime.getDayOfWeek()) && combinedHourPredicate.apply(dateTime.getHour()); }; }  static boolean isEmpty(TimeWindow timeWindow); static Supplier<Boolean> isInTimeWindowPredicate(TitusRuntime titusRuntime, TimeWindow timeWindow); static Supplier<Boolean> isInTimeWindowPredicate(TitusRuntime titusRuntime, Collection<TimeWindow> timeWindows);  }
@Test public void testEmptyTimeWindowPredicate() { Supplier<Boolean> predicate = TimeWindowFunctions.isInTimeWindowPredicate(titusRuntime, TimeWindow.empty()); assertThat(predicate.get()).isTrue(); }
@Test public void testTimeWindowPredicateInUtc() { TimeWindow timeWindow = TimeWindow.newBuilder() .withDays(Day.Monday) .withwithHourlyTimeWindows(8, 16) .build(); Supplier<Boolean> predicate = TimeWindowFunctions.isInTimeWindowPredicate(titusRuntime, timeWindow); clock.jumpForwardTo(DayOfWeek.MONDAY).resetTime(7, 0, 0); assertThat(predicate.get()).isFalse(); clock.resetTime(11, 0, 0); assertThat(predicate.get()).isTrue(); clock.resetTime(17, 0, 0); assertThat(predicate.get()).isFalse(); }
@Test public void testTimeWindowPredicateInPst() { TimeWindow timeWindow = TimeWindow.newBuilder() .withDays(Day.Monday) .withwithHourlyTimeWindows(8, 16) .withTimeZone("PST") .build(); Supplier<Boolean> predicate = TimeWindowFunctions.isInTimeWindowPredicate(titusRuntime, timeWindow); clock.jumpForwardTo(DayOfWeek.MONDAY).resetTime(10, 0, 0); assertThat(predicate.get()).isFalse(); clock.resetTime(16, 0, 0); assertThat(predicate.get()).isTrue(); clock.resetTime(20, 0, 0); }
@Test public void testMultipleTimeWindowsPredicate() { TimeWindow timeWindow1 = TimeWindow.newBuilder() .withDays(Day.Monday, Day.Tuesday, Day.Wednesday, Day.Thursday) .withwithHourlyTimeWindows(8, 11, 13, 16) .build(); TimeWindow timeWindow2 = TimeWindow.newBuilder() .withDays(Day.Friday) .withwithHourlyTimeWindows(8, 13) .build(); Supplier<Boolean> predicate = TimeWindowFunctions.isInTimeWindowPredicate(titusRuntime, asList(timeWindow1, timeWindow2)); clock.jumpForwardTo(DayOfWeek.WEDNESDAY).resetTime(7, 0, 0); assertThat(predicate.get()).isFalse(); clock.jumpForwardTo(DayOfWeek.WEDNESDAY).resetTime(10, 0, 0); assertThat(predicate.get()).isTrue(); clock.jumpForwardTo(DayOfWeek.WEDNESDAY).resetTime(12, 0, 0); assertThat(predicate.get()).isFalse(); clock.jumpForwardTo(DayOfWeek.WEDNESDAY).resetTime(15, 0, 0); assertThat(predicate.get()).isTrue(); clock.jumpForwardTo(DayOfWeek.WEDNESDAY).resetTime(18, 0, 0); assertThat(predicate.get()).isFalse(); clock.jumpForwardTo(DayOfWeek.FRIDAY).resetTime(7, 0, 0); assertThat(predicate.get()).isFalse(); clock.jumpForwardTo(DayOfWeek.FRIDAY).resetTime(12, 0, 0); assertThat(predicate.get()).isTrue(); clock.jumpForwardTo(DayOfWeek.FRIDAY).resetTime(15, 0, 0); assertThat(predicate.get()).isFalse(); }