diff --git a/src/main/java/com/noenv/cronutils/CronScheduler.java b/src/main/java/com/noenv/cronutils/CronScheduler.java index 8dbe5a9..d9048f7 100644 --- a/src/main/java/com/noenv/cronutils/CronScheduler.java +++ b/src/main/java/com/noenv/cronutils/CronScheduler.java @@ -10,6 +10,8 @@ import io.vertx.core.Handler; import io.vertx.core.Vertx; +import java.time.ZoneId; + /** * Creates CronScheduler instances. * @@ -27,7 +29,7 @@ public interface CronScheduler { */ static CronScheduler create(Vertx vertx, String cron) { final CronDefinition definition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); - return new CronSchedulerImpl(vertx, cron, definition); + return new CronSchedulerImpl(vertx, cron, definition, ZoneId.systemDefault()); } /** @@ -40,7 +42,34 @@ static CronScheduler create(Vertx vertx, String cron) { */ static CronScheduler create(Vertx vertx, String cron, CronType type) { final CronDefinition definition = CronDefinitionBuilder.instanceDefinitionFor(type); - return new CronSchedulerImpl(vertx, cron, definition); + return new CronSchedulerImpl(vertx, cron, definition, ZoneId.systemDefault()); + } + + /** + * Create a CronScheduler. + * + * @param vertx the Vert.x instance + * @param cron the cron expression + * @param zoneId the timezone id + * @return the instance + */ + static CronScheduler create(Vertx vertx, String cron, String zoneId) { + final CronDefinition definition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); + return new CronSchedulerImpl(vertx, cron, definition, ZoneId.of(zoneId)); + } + + /** + * Create a CronScheduler. + * + * @param vertx the Vert.x instance + * @param cron the cron expression + * @param type the cron type + * @param zoneId the timezone id + * @return the instance + */ + static CronScheduler create(Vertx vertx, String cron, CronType type, String zoneId) { + final CronDefinition definition = CronDefinitionBuilder.instanceDefinitionFor(type); + return new CronSchedulerImpl(vertx, cron, definition, ZoneId.of(zoneId)); } /** @@ -52,8 +81,8 @@ static CronScheduler create(Vertx vertx, String cron, CronType type) { * @return the instance */ @GenIgnore - static CronScheduler create(Vertx vertx, String cron, CronDefinition definition) { - return new CronSchedulerImpl(vertx, cron, definition); + static CronScheduler create(Vertx vertx, String cron, CronDefinition definition, ZoneId zoneId) { + return new CronSchedulerImpl(vertx, cron, definition, zoneId); } /** @@ -67,4 +96,6 @@ static CronScheduler create(Vertx vertx, String cron, CronDefinition definition) void cancel(); boolean active(); + + String zoneId(); } diff --git a/src/main/java/com/noenv/cronutils/impl/CronSchedulerImpl.java b/src/main/java/com/noenv/cronutils/impl/CronSchedulerImpl.java index 2d7654d..cc1a6c7 100644 --- a/src/main/java/com/noenv/cronutils/impl/CronSchedulerImpl.java +++ b/src/main/java/com/noenv/cronutils/impl/CronSchedulerImpl.java @@ -8,6 +8,7 @@ import io.vertx.core.Vertx; import java.time.Duration; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Objects; @@ -21,13 +22,15 @@ public class CronSchedulerImpl implements CronScheduler, Handler { private final Vertx vertx; private final ExecutionTime expression; + private final ZoneId zoneId; private Handler handler; private long timerId; private ZonedDateTime executionTime; - public CronSchedulerImpl(final Vertx vertx, final String cronExpression, final CronDefinition definition) { + public CronSchedulerImpl(final Vertx vertx, final String cronExpression, final CronDefinition definition, final ZoneId zoneId) { this.vertx = vertx; this.timerId = -1L; + this.zoneId = zoneId; final CronParser parser = new CronParser(definition); this.expression = ExecutionTime.forCron(parser.parse(cronExpression)); @@ -67,8 +70,13 @@ public boolean active() { return timerId >= 0L; } + @Override + public String zoneId() { + return zoneId.getId(); + } + private void scheduleNextTimer(final long addMilliseconds) { - final ZonedDateTime now = ZonedDateTime.now(); + final ZonedDateTime now = ZonedDateTime.now(zoneId); if(executionTime == null) { executionTime = now; } diff --git a/src/test/java/com/noenv/cronutils/CronSchedulerTest.java b/src/test/java/com/noenv/cronutils/CronSchedulerTest.java index f9d34e1..3754d91 100644 --- a/src/test/java/com/noenv/cronutils/CronSchedulerTest.java +++ b/src/test/java/com/noenv/cronutils/CronSchedulerTest.java @@ -6,7 +6,9 @@ import io.vertx.test.core.VertxTestBase; import org.junit.Test; +import java.time.DateTimeException; import java.time.YearMonth; +import java.time.ZoneId; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -21,6 +23,7 @@ public void testCronExpression() throws IllegalArgumentException, InterruptedExc .schedule(s -> latch.countDown()); latch.await(5, TimeUnit.SECONDS); assertTrue(scheduler.active()); + assertEquals(ZoneId.systemDefault().getId(), scheduler.zoneId()); scheduler.cancel(); assertEquals(0, latch.getCount()); } @@ -100,11 +103,43 @@ public void testCronCustomDefinition() throws IllegalArgumentException, Interrup .withDayOfWeek().withValidRange(1, 7).withMondayDoWValue(2).supportsHash().supportsL().supportsQuestionMark().and() .withYear().withValidRange(1970, maxYear).withStrictRange().optional().and() .withCronValidation(CronConstraintsFactory.ensureEitherDayOfWeekOrDayOfMonth()) - .instance()) + .instance(), ZoneId.systemDefault()) .schedule(s -> latch.countDown()); latch.await(5, TimeUnit.SECONDS); assertTrue(scheduler.active()); scheduler.cancel(); assertEquals(0, latch.getCount()); } + + @Test + public void testCronZonedExpression() throws IllegalArgumentException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(3); + CronScheduler scheduler = CronScheduler + .create(vertx, "0/1 * * * * ?", CronType.QUARTZ, "UTC") + .schedule(s -> latch.countDown()); + latch.await(5, TimeUnit.SECONDS); + assertTrue(scheduler.active()); + assertEquals("UTC", scheduler.zoneId()); + scheduler.cancel(); + assertEquals(0, latch.getCount()); + } + + @Test + public void testCronZonedExpressionWithDefaultType() throws IllegalArgumentException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(3); + CronScheduler scheduler = CronScheduler + .create(vertx, "0/1 * * * * ?", "Z") + .schedule(s -> latch.countDown()); + latch.await(5, TimeUnit.SECONDS); + assertTrue(scheduler.active()); + assertEquals("Z", scheduler.zoneId()); + scheduler.cancel(); + assertEquals(0, latch.getCount()); + } + + @Test(expected= DateTimeException.class) + public void testInvalidZoneId() throws IllegalArgumentException { + CronScheduler + .create(vertx, "0/1 * * * * ?", CronType.QUARTZ, "WrongId"); + } }