Java Code Examples for com.cronutils.model.time.ExecutionTime#nextExecution()

The following examples show how to use com.cronutils.model.time.ExecutionTime#nextExecution() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Issue305Test.java    From cron-utils with Apache License 2.0 8 votes vote down vote up
@Test
public void testIssue305(){
    CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
    CronParser parser = new CronParser(cronDefinition);
    Cron cron = parser.parse("0 0 0 15 8 ? 2015-2099/2");

    ExecutionTime executionTime = ExecutionTime.forCron(cron);
    Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(ZonedDateTime.of(2015, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
    Set<ZonedDateTime> dates = new LinkedHashSet<>();
    while (!nextExecution.get().isAfter(ZonedDateTime.of(2020, 12, 31, 0, 0, 0, 0, ZoneId.of("UTC")))) {
        dates.add(nextExecution.get());
        nextExecution = executionTime.nextExecution(nextExecution.get());
    }
    Set<Integer> years = dates.stream().map(d->d.getYear()).collect(Collectors.toSet());
    Set<Integer> expectedYears = new HashSet<>();
    expectedYears.add(2015);
    expectedYears.add(2017);
    expectedYears.add(2019);
    assertEquals(expectedYears, years);
}
 
Example 2
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 6 votes vote down vote up
/**
 * Issue #112: Calling nextExecution exactly on the first instant of the fallback hour (after the DST ends) makes it go back to DST.
 * https://github.com/jmrozanec/cron-utils/issues/112
 */
@Test
public void testWrongNextExecutionOnDSTEnd() {
    final ZoneId zone = ZoneId.of("America/Sao_Paulo");

    //2016-02-20T23:00-03:00[America/Sao_Paulo], first minute of fallback hour
    final ZonedDateTime date = ZonedDateTime.ofInstant(Instant.ofEpochMilli(1456020000000L), zone);
    final ZonedDateTime expected = ZonedDateTime.ofInstant(Instant.ofEpochMilli(1456020000000L + 60000), zone);

    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("* * * * *"));
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
    if (nextExecution.isPresent()) {
        assertEquals(expected, nextExecution.get());
    } else {
        fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
    }
}
 
Example 3
Source File: Issue340Test.java    From cron-utils with Apache License 2.0 6 votes vote down vote up
@Test
public void testDayOfWeekRollover() {
    // Every Friday to Tuesday (Fri, Sat, Sun, Mon, Tue) at 5 AM
    String schedule = "0 0 5 ? * FRI-TUE *";
    // Java DayOfWeek is MON (1) to SUN (7)
    Set<Integer> validDaysOfWeek = Sets.newSet(1, 2, 5, 6, 7);
    CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
    CronParser parser = new CronParser(cronDefinition);
    Cron quartzCron = parser.parse(schedule);

    ZonedDateTime time = ZonedDateTime.now();
    ExecutionTime executionTime = ExecutionTime.forCron(quartzCron);

    // Check the next 100 execution times
    for (int i = 0; i < 100; i++) {
        Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(time);
        Assert.assertTrue(nextExecution.isPresent());
        time = nextExecution.get();
        int dayOfWeek = time.getDayOfWeek().getValue();
        Assert.assertTrue(validDaysOfWeek.contains(dayOfWeek));
        Assert.assertEquals(5, time.getHour());
        Assert.assertEquals(0, time.getMinute());
        Assert.assertEquals(0, time.getSecond());
    }
}
 
Example 4
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 6 votes vote down vote up
/**
 * Issue #45: next execution does not match expected date. Result is not in same timezone as reference date.
 */
@Test
public void testMondayWeekdayNextExecution() {
    final String crontab = "* * * * 1";
    final CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX);
    final CronParser parser = new CronParser(cronDefinition);
    final Cron cron = parser.parse(crontab);
    final ZonedDateTime date = ZonedDateTime.parse("2015-10-13T17:26:54.468-07:00");
    final ExecutionTime executionTime = ExecutionTime.forCron(cron);
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
    if (nextExecution.isPresent()) {
        assertEquals(ZonedDateTime.parse("2015-10-19T00:00:00.000-07:00"), nextExecution.get());
    } else {
        fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
    }
}
 
Example 5
Source File: Issue394Test.java    From cron-utils with Apache License 2.0 6 votes vote down vote up
@Test
public void testEveryMondayAt0900hours() {
    String cron = "0 0 9 * * MON";

    CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(SPRING);
    CronParser parser = new CronParser(cronDefinition);
    ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(cron));
    ZonedDateTime now = ZonedDateTime.now();
    Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(now);
    assertTrue(nextExecution.isPresent());
    // Should be the next Monday at 0900 hours
    assertEquals(DayOfWeek.MONDAY, nextExecution.get().getDayOfWeek());
    assertEquals(9, nextExecution.get().getHour());
    // The next execution after that should also be a Monday at 0900 hours, the following week
    ZonedDateTime nextExpectedExecution = nextExecution.get().plusWeeks(1);
    nextExecution = executionTime.nextExecution(nextExecution.get());
    assertTrue(nextExecution.isPresent());
    assertEquals(DayOfWeek.MONDAY, nextExecution.get().getDayOfWeek());
    assertEquals(9, nextExecution.get().getHour());
    assertEquals(nextExpectedExecution, nextExecution.get());
}
 
Example 6
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 6 votes vote down vote up
/**
 * Issue #79: Next execution skipping valid date.
 */
@Test
public void testNextExecution2014() {
    final String crontab = "0 8 * * 1";//m,h,dom,m,dow ; every monday at 8AM
    final CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX);
    final CronParser parser = new CronParser(cronDefinition);
    final Cron cron = parser.parse(crontab);
    final ZonedDateTime date = ZonedDateTime.parse("2014-11-30T00:00:00Z");
    final ExecutionTime executionTime = ExecutionTime.forCron(cron);
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
    if (nextExecution.isPresent()) {
        assertEquals(ZonedDateTime.parse("2014-12-01T08:00:00Z"), nextExecution.get());
    } else {
        fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
    }

}
 
Example 7
Source File: Issue418Test.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
@Test
public void testQuartzEvery7DaysStartingSunday() {
    final CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
    final CronParser parser = new CronParser(cronDefinition);
    final ExecutionTime execTime = ExecutionTime.forCron(parser.parse("0 0 2 ? * 1/7 *"));

    final ZonedDateTime startDate = ZonedDateTime.of(
            LocalDate.of(2020, 4, 1),
            LocalTime.of(3, 0),
            ZoneId.systemDefault()
    );
    final ZonedDateTime[] expectedDates = {
            ZonedDateTime.of(
                    LocalDate.of(2020, 4, 5),
                    LocalTime.of(2, 0),
                    ZoneId.systemDefault()
            ),
            ZonedDateTime.of(
                    LocalDate.of(2020, 4, 12),
                    LocalTime.of(2, 0),
                    ZoneId.systemDefault()
            )
    };

    Optional<ZonedDateTime> nextExecution = execTime.nextExecution(startDate);
    assert(nextExecution.isPresent());
    assertEquals( expectedDates[0], nextExecution.get());

    nextExecution = execTime.nextExecution(nextExecution.get());
    assert(nextExecution.isPresent());
    assertEquals( expectedDates[1], nextExecution.get());
}
 
Example 8
Source File: ScheduleHelper.java    From ResearchStack with Apache License 2.0 5 votes vote down vote up
public static Date nextSchedule(String cronString, Date lastExecution) {
    DateTime now = new DateTime(lastExecution);
    CronParser cronParser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    Cron cron = cronParser.parse(cronString);

    ExecutionTime executionTime = ExecutionTime.forCron(cron);
    DateTime nextExecution = executionTime.nextExecution(now);

    return nextExecution.toDate();
}
 
Example 9
Source File: Issue406Test.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
@Test
public void testDayOfWeekIsCorrectlyApplied() {
    // GIVEN a spring cron operating at 1AM every weekday
    final CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.SPRING);
    final CronParser parser = new CronParser(cronDefinition);
    final ExecutionTime execTime = ExecutionTime.forCron(parser.parse("0 0 1 * * MON-FRI"));

    // WHEN I get the next execution at 3AM on Saturday
    final ZonedDateTime threeAmFifthJanuary2019 = ZonedDateTime.of(
        LocalDate.of(2019, 1, 5),
        LocalTime.of(3, 0),
        ZoneId.systemDefault()
    );
    final Optional<ZonedDateTime> nextExecution = execTime.nextExecution(threeAmFifthJanuary2019);
    
    // THEN the result is 1AM on Monday
    assertEquals(
        Optional.of(
                ZonedDateTime.of(
                LocalDate.of(2019, 1, 7),
                LocalTime.of(1, 0),
                ZoneId.systemDefault()
            )
        ),
        nextExecution
    );
}
 
Example 10
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
/**
 * https://github.com/jmrozanec/cron-utils/issues/336
 */
@Test
public void testEveryDayPerWeek() {
    CronParser cronParser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    // every 3 days - Sun (1), Wed (4), Sat (7)
    String cronString = "0 0 * * */3";
    Cron cron = cronParser.parse(cronString);
    ExecutionTime executionTime = ExecutionTime.forCron(cron);
    Optional<ZonedDateTime> nextExecution = executionTime
            .nextExecution(ZonedDateTime.of(2018, 2, 8, 0, 0, 0, 0, ZoneId.of("UTC")));
    assertTrue(nextExecution.isPresent());
    assertEquals(ZonedDateTime.of(2018, 2, 10, 0, 0, 0, 0, ZoneId.of("UTC")), nextExecution.get());
}
 
Example 11
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
/**
 * Issue #125: Prints stack trace for NoSuchValueException for expressions with comma-separated values
 * https://github.com/jmrozanec/cron-utils/issues/125
 */
@Test
public void testNextExecutionProducesStackTraces() {
    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("45 1,13 * * *"));
    executionTime.nextExecution(ZonedDateTime.parse("2016-05-24T01:02:50Z"));
}
 
Example 12
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
/**
 * Issue #92: Next execution skipping valid date.
 */
@Test
public void testNextExecution2016() {
    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("1 0 * * tue"));
    final ZonedDateTime date = ZonedDateTime.parse("2016-05-24T01:02:50Z");
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
    if (nextExecution.isPresent()) {
        assertEquals(ZonedDateTime.parse("2016-05-31T00:01:00Z"), nextExecution.get());
    } else {
        fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
    }
}
 
Example 13
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
/**
 * Issue #37: for pattern "every 10 minutes", nextExecution returns a date from past.
 */
@Test
public void testEveryTenMinutesNextExecution() {
    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("*/10 * * * *"));
    final ZonedDateTime time = ZonedDateTime.parse("2015-09-05T13:43:00.000-07:00");
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(time);
    if (nextExecution.isPresent()) {
        assertEquals(ZonedDateTime.parse("2015-09-05T13:50:00.000-07:00"), nextExecution.get());
    } else {
        fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
    }
}
 
Example 14
Source File: CronParserQuartzIntegrationTest.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
/**
 * Issue #151: L-7 in day of month should work to find the day 7 days prior to the last day of the month.
 */
@Test
public void testLSupportedInDoMRangeNextExecutionCalculation() {
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("0 15 10 L-7 * ?"));
    final ZonedDateTime now = ZonedDateTime.parse("2017-01-31T10:00:00Z");
    final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(now);
    if (nextExecution.isPresent()) {
        final ZonedDateTime assertDate = ZonedDateTime.parse("2017-02-21T10:15:00Z");
        assertEquals(assertDate, nextExecution.get());
    } else {
        fail("next execution was not present");
    }
}
 
Example 15
Source File: Issue215Test.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
private void checkNextExecution(final LocalDateTime startDate, final LocalDateTime expectedNextExecution, final Cron cron) {
    final ExecutionTime executionTime = ExecutionTime.forCron(cron);
    final ZonedDateTime zonedDateTime = ZonedDateTime.of(startDate, ZoneId.systemDefault());
    final Optional<ZonedDateTime> next = executionTime.nextExecution(zonedDateTime);
    assert (next.isPresent());
    assertEquals(ZonedDateTime.of(expectedNextExecution, ZoneId.systemDefault()), next.get());
}
 
Example 16
Source File: Issue363Test.java    From cron-utils with Apache License 2.0 5 votes vote down vote up
@Test
public void everySecondOfMinute01Test() {
    // every second of the first minute of every hour/day/year
    String cronExpression = "* 1 * * * ?";
    CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
    ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(cronExpression));

    ZonedDateTime now = ZonedDateTime.of(2019, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
    Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(now);

    assertTrue(nextExecution.isPresent());
    // First match should be 2019-01-01T00:01:00Z
    ZonedDateTime expectedTime = ZonedDateTime.of(2019, 1, 1, 0, 1, 0, 0, ZoneOffset.UTC);
    assertEquals(expectedTime, nextExecution.get());

    // Should also match the next 59 seconds
    for (int i = 1; i <= 59; i++) {
        nextExecution = executionTime.nextExecution(nextExecution.get());
        assertTrue(nextExecution.isPresent());
        assertEquals(expectedTime.plusSeconds(i), nextExecution.get());
    }

    // After the every second of 00:01, it the next execution should be at 01:01:00Z
    nextExecution = executionTime.nextExecution(ZonedDateTime.of(2019, 1, 1, 0, 1, 59, 0, ZoneOffset.UTC));
    assertTrue(nextExecution.isPresent());
    expectedTime = ZonedDateTime.of(2019, 1, 1, 1, 1, 0, 0, ZoneOffset.UTC);
    assertEquals(expectedTime, nextExecution.get());
}
 
Example 17
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 4 votes vote down vote up
private Optional<ZonedDateTime> getNextExecutionFor(final Cron cron, final ZonedDateTime dateTime) {
    final ExecutionTime executionTime = ExecutionTime.forCron(cron);
    return  executionTime.nextExecution(dateTime);
}
 
Example 18
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 4 votes vote down vote up
/**
 * Issue #112: Calling nextExecution on a date-time during the overlap hour of DST causes an incorrect offset
 * to be returned.
 */
@Test
public void testDSTOverlap() {
    final ZoneId zoneId = ZONE_ID_NEW_YORK;

    // For the America/New_York time zone, DST ends (UTC-4:00 to UTC-5:00 / EDT -> EST) at 2:00 AM
    // on the these days for the years 2015-2026:
    final Set<LocalDate> dstDates = new HashSet<>();
    dstDates.add(LocalDate.of(2015, Month.NOVEMBER, 1));
    dstDates.add(LocalDate.of(2016, Month.NOVEMBER, 6));
    dstDates.add(LocalDate.of(2017, Month.NOVEMBER, 5));
    dstDates.add(LocalDate.of(2018, Month.NOVEMBER, 4));
    dstDates.add(LocalDate.of(2019, Month.NOVEMBER, 3));
    dstDates.add(LocalDate.of(2020, Month.NOVEMBER, 1));
    dstDates.add(LocalDate.of(2021, Month.NOVEMBER, 7));
    dstDates.add(LocalDate.of(2022, Month.NOVEMBER, 6));
    dstDates.add(LocalDate.of(2023, Month.NOVEMBER, 5));
    dstDates.add(LocalDate.of(2024, Month.NOVEMBER, 3));
    dstDates.add(LocalDate.of(2025, Month.NOVEMBER, 2));
    dstDates.add(LocalDate.of(2026, Month.NOVEMBER, 1));

    // Starting at 12 AM Nov. 1, 2015
    ZonedDateTime date = ZonedDateTime.of(2015, 11, 1, 0, 0, 0, 0, zoneId);

    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    // Scheduling pattern for 1:30 AM for the first 7 days of every November
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("30 1 1-7 11 *"));

    final ZoneOffset easternDaylightTimeOffset = ZoneOffset.ofHours(-4);
    final ZoneOffset easternStandardTimeOffset = ZoneOffset.ofHours(-5);

    for (int year = 2015; year <= 2026; year++) {
        boolean pastDSTEnd = false;
        int dayOfMonth = 1;
        while (dayOfMonth < 8) {
            final LocalDateTime expectedLocalDateTime = LocalDateTime.of(year, Month.NOVEMBER, dayOfMonth, 1, 30);
            final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
            assert (nextExecution.isPresent());
            date = nextExecution.get();

            final ZoneOffset expectedOffset = pastDSTEnd ? easternStandardTimeOffset : easternDaylightTimeOffset;

            if (dstDates.contains(LocalDate.of(year, Month.NOVEMBER, dayOfMonth))) {
                if (!pastDSTEnd) {
                    // next iteration should be past the DST transition
                    pastDSTEnd = true;
                } else {
                    dayOfMonth++;
                }
            } else {
                dayOfMonth++;
            }
            assertEquals(ZonedDateTime.ofInstant(expectedLocalDateTime, expectedOffset, zoneId), date);
        }
    }
}
 
Example 19
Source File: ExecutionTimeUnixIntegrationTest.java    From cron-utils with Apache License 2.0 4 votes vote down vote up
/**
 * Test that a cron expression that only runs at a certain time that falls inside the DST start gap
 * does not run on the DST start day. Ex. 2:15 AM is an invalid local time for the America/New_York
 * time zone on the DST start days.
 */
@Test
public void testDSTGap() {
    final ZoneId zoneId = ZONE_ID_NEW_YORK;
    final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX));
    // Run at 2:15 AM each day for March 7 to 14
    final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("15 2 7-14 3 *"));

    // Starting at 12 AM March. 7, 2015
    ZonedDateTime date = ZonedDateTime.of(2015, 3, 7, 0, 0, 0, 0, zoneId);

    // For America/New_York timezone, DST starts at 2 AM local time and moves forward 1 hour
    // DST dates for 2015-2026
    final Map<Integer, LocalDate> dstDates = new HashMap<>();
    dstDates.put(2015, LocalDate.of(2015, Month.MARCH, 8));
    dstDates.put(2016, LocalDate.of(2016, Month.MARCH, 13));
    dstDates.put(2017, LocalDate.of(2017, Month.MARCH, 12));
    dstDates.put(2018, LocalDate.of(2018, Month.MARCH, 11));
    dstDates.put(2019, LocalDate.of(2019, Month.MARCH, 10));
    dstDates.put(2020, LocalDate.of(2020, Month.MARCH, 8));
    dstDates.put(2021, LocalDate.of(2021, Month.MARCH, 14));
    dstDates.put(2022, LocalDate.of(2022, Month.MARCH, 13));
    dstDates.put(2023, LocalDate.of(2023, Month.MARCH, 12));
    dstDates.put(2024, LocalDate.of(2024, Month.MARCH, 10));
    dstDates.put(2025, LocalDate.of(2025, Month.MARCH, 9));
    dstDates.put(2026, LocalDate.of(2026, Month.MARCH, 8));

    final ZoneOffset easternDaylightTimeOffset = ZoneOffset.ofHours(-4);
    final ZoneOffset easternStandardTimeOffset = ZoneOffset.ofHours(-5);
    for (int year = 2015; year <= 2026; year++) {
        final LocalDate dstDateForYear = dstDates.get(year);
        boolean isPastDSTStart = false;
        int dayOfMonth = 7;
        while (dayOfMonth < 15) {
            final LocalDateTime localDateTime = LocalDateTime.of(year, Month.MARCH, dayOfMonth, 2, 15);
            // skip the DST start days... 2:15 AM does not exist in the local time
            if (localDateTime.toLocalDate().isEqual(dstDateForYear)) {
                dayOfMonth++;
                isPastDSTStart = true;
                continue;
            }
            final ZoneOffset expectedOffset = isPastDSTStart ? easternDaylightTimeOffset : easternStandardTimeOffset;
            final ZonedDateTime expectedDateTime = ZonedDateTime.ofLocal(localDateTime, zoneId, expectedOffset);

            final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(date);
            assert (nextExecution.isPresent());
            date = nextExecution.get();
            assertEquals(expectedDateTime, date);
            dayOfMonth++;
        }
    }
}
 
Example 20
Source File: MaintenanceScheduleHelper.java    From hawkbit with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Calculate the next available maintenance window.
 *
 * @param cronSchedule
 *            is a cron expression with 6 mandatory fields and 1 last
 *            optional field: "second minute hour dayofmonth month weekday
 *            year".
 * @param duration
 *            in HH:mm:ss format specifying the duration of a maintenance
 *            window, for example 00:30:00 for 30 minutes.
 * @param timezone
 *            is the time zone specified as +/-hh:mm offset from UTC. For
 *            example +02:00 for CET summer time and +00:00 for UTC. The
 *            start time of a maintenance window calculated based on the
 *            cron expression is relative to this time zone.
 *
 * @return { @link Optional<ZonedDateTime>} of the next available window. In
 *         case there is none, or there are maintenance window validation
 *         errors, returns empty value.
 * 
 */
// Exception squid:S1166 - if there are validation error(format of cron
// expression or duration is wrong), we simply return empty value
@SuppressWarnings("squid:S1166")
public static Optional<ZonedDateTime> getNextMaintenanceWindow(final String cronSchedule, final String duration,
        final String timezone) {
    try {
        final ExecutionTime scheduleExecutor = ExecutionTime.forCron(getCronFromExpression(cronSchedule));
        final ZonedDateTime now = ZonedDateTime.now(ZoneOffset.of(timezone));
        final ZonedDateTime after = now.minus(convertToISODuration(duration));
        final ZonedDateTime next = scheduleExecutor.nextExecution(after);
        return Optional.of(next);
    } catch (final RuntimeException ignored) {
        return Optional.empty();
    }
}