diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java index 5f5cf4e280..68d127c72f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java @@ -71,7 +71,19 @@ public class CronSequenceGenerator { /** - * Construct a {@link CronSequenceGenerator} from the pattern provided. + * Construct a {@link CronSequenceGenerator} from the pattern provided, + * using the default {@link TimeZone}. + * @param expression a space-separated list of time fields + * @throws IllegalArgumentException if the pattern cannot be parsed + * @see java.util.TimeZone#getDefault() + */ + public CronSequenceGenerator(String expression) { + this(expression, TimeZone.getDefault()); + } + + /** + * Construct a {@link CronSequenceGenerator} from the pattern provided, + * using the specified {@link TimeZone}. * @param expression a space-separated list of time fields * @param timeZone the TimeZone to use for generated trigger times * @throws IllegalArgumentException if the pattern cannot be parsed @@ -114,12 +126,17 @@ public class CronSequenceGenerator { calendar.setTimeZone(this.timeZone); calendar.setTime(date); - // Truncate to the next whole second - calendar.add(Calendar.SECOND, 1); + // First, just reset the milliseconds and try to calculate from there... calendar.set(Calendar.MILLISECOND, 0); - + long originalTimestamp = calendar.getTimeInMillis(); doNext(calendar, calendar.get(Calendar.YEAR)); + if (calendar.getTimeInMillis() == originalTimestamp) { + // We arrived at the original timestamp - round up to the next whole second and try again... + calendar.add(Calendar.SECOND, 1); + doNext(calendar, calendar.get(Calendar.YEAR)); + } + return calendar.getTime(); } diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronSequenceGeneratorTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronSequenceGeneratorTests.java new file mode 100644 index 0000000000..491706f9e3 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronSequenceGeneratorTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.support; + +import java.util.Date; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class CronSequenceGeneratorTests { + + @Test + public void testAt50Seconds() { + assertEquals(new Date(2012, 6, 2, 1, 0), + new CronSequenceGenerator("*/15 * 1-4 * * *").next(new Date(2012, 6, 1, 9, 53, 50))); + } + + @Test + public void testAt0Seconds() { + assertEquals(new Date(2012, 6, 2, 1, 0), + new CronSequenceGenerator("*/15 * 1-4 * * *").next(new Date(2012, 6, 1, 9, 53))); + } + + @Test + public void testAt0Minutes() { + assertEquals(new Date(2012, 6, 2, 1, 0), + new CronSequenceGenerator("0 */2 1-4 * * *").next(new Date(2012, 6, 1, 9, 0))); + } + +} diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java index a99bffa1ed..90acc959b3 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronTriggerTests.java @@ -41,7 +41,7 @@ import static org.junit.Assert.*; @RunWith(Parameterized.class) public class CronTriggerTests { - private Calendar calendar = new GregorianCalendar(); + private final Calendar calendar = new GregorianCalendar(); private final Date date; @@ -49,8 +49,8 @@ public class CronTriggerTests { public CronTriggerTests(Date date, TimeZone timeZone) { - this.timeZone = timeZone; this.date = date; + this.timeZone = timeZone; } @Parameters @@ -66,6 +66,7 @@ public class CronTriggerTests { calendar.set(Calendar.MILLISECOND, 0); } + @Before public void setUp() { calendar.setTimeZone(timeZone);