Skip to content

Commit

Permalink
Issue jakartaee#274 ArrayIndexOutOfBoundsException from DST handling …
Browse files Browse the repository at this point in the history
…code

Signed-off-by: Nathan Rauh <[email protected]>
  • Loading branch information
njr-11 authored and KyleAure committed Aug 24, 2023
1 parent c673ba1 commit dbc2507
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 8 deletions.
19 changes: 12 additions & 7 deletions api/src/main/java/jakarta/enterprise/concurrent/CronTrigger.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021,2022 Contributors to the Eclipse Foundation
* Copyright (c) 2021,2023 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -501,12 +501,17 @@ private ZonedDateTime nextDayOfMonth(final int d, final int l, final int m,
*/
private ZonedDateTime nextHour(final int h, final int d, final int l, final int dayOfMonth,
final int m, final int year, final ZonedDateTime time) {
ZonedDateTime dst = ZonedDateTime.of(year, months[m], dayOfMonth,
hours[h], minutes[0], seconds[0], 0, time.getZone());
ZonedDateTime std = dst.plusHours(1);
if (dst.getHour() == std.getHour() && time.isAfter(dst) && time.isBefore(std)) {
return std; // Daylight Saving Time --> Standard Time
} else if (h + 1 < hours.length) {
// Determine if the same hour can be kept due to transition from Daylight Saving Time to Standard Time:
if (h >= 0) {
ZonedDateTime dst = ZonedDateTime.of(year, months[m], dayOfMonth,
hours[h], minutes[0], seconds[0], 0, time.getZone());
ZonedDateTime std = dst.plusHours(1);
if (dst.getHour() == std.getHour() && time.isAfter(dst) && time.isBefore(std)) {
return std; // Daylight Saving Time --> Standard Time
}
}

if (h + 1 < hours.length) {
return ZonedDateTime.of(year, months[m], dayOfMonth,
hours[h + 1], minutes[0], seconds[0], 0, time.getZone());
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Contributors to the Eclipse Foundation
* Copyright (c) 2021,2023 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -22,6 +22,7 @@
import java.time.Month;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;

import org.junit.Test;

Expand Down Expand Up @@ -316,6 +317,87 @@ public void testCronTriggerJavaDocExample() {
assertEquals(ZonedDateTime.of(2021, 9, 30, 10, 0, 0, 0, zone), time); // last
}

/**
* Verify that a cron trigger that runs daily at noon can be properly applied to all hours of the day.
*/
@Test
public void testDailyAtNoon() {
CronTrigger trigger = new CronTrigger("0 12 * * *", ZoneOffset.UTC);
ZonedDateTime next;

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 0, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 1, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 2, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 3, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 4, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 5, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 6, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 7, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 8, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 9, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 10, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 11, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 22, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 13, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 14, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 15, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 16, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 17, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 18, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 19, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 20, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 21, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 22, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);

next = trigger.getNextRunTime(null, ZonedDateTime.of(2023, 4, 22, 23, 0, 0, 0, ZoneOffset.UTC));
assertEquals(ZonedDateTime.of(2023, 4, 23, 12, 0, 0, 0, ZoneOffset.UTC), next);
}

/**
* Specify daysOfMonth as a cron expression.
*/
Expand Down

0 comments on commit dbc2507

Please sign in to comment.