diff --git a/pom.xml b/pom.xml index c542448..0d0d263 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ fc.cron cron jar - 1.1 + 1.2 cron https://github.com/frode-carlsen/cron diff --git a/src/main/java/fc/cron/CronExpression.java b/src/main/java/fc/cron/CronExpression.java index 3c15b34..8d641bd 100644 --- a/src/main/java/fc/cron/CronExpression.java +++ b/src/main/java/fc/cron/CronExpression.java @@ -32,7 +32,7 @@ import org.joda.time.MutableDateTime; * Parser for unix-like cron expressions: Cron expressions allow specifying combinations of criteria for time * such as: "Each Monday-Friday at 08:00" or "Every last friday of the month at 01:30" *

- * A cron expressions consists of 6 mandatory fields separated by space.
+ * A cron expressions consists of 5 or 6 mandatory fields (seconds may be omitted) separated by space.
* These are: * * @@ -44,7 +44,7 @@ import org.joda.time.MutableDateTime; * * * - * + * * *
Special Characters
SecondsSeconds (may be omitted)  * 0-59  @@ -143,7 +143,6 @@ public class CronExpression { this.to = to; this.names = names; } - } private final String expr; @@ -154,23 +153,39 @@ public class CronExpression { private final SimpleField monthField; private final DayOfMonthField dayOfMonthField; - public CronExpression(String expr) { + public CronExpression(final String expr) { + this(expr, true); + } + + public CronExpression(final String expr, final boolean withSeconds) { if (expr == null) { - throw new IllegalArgumentException("expr is null"); - } - this.expr = expr; - String[] parts = expr.split("\\s+"); - if (parts.length != 6) { - throw new IllegalArgumentException(String.format("Invalid cronexpression [%s], expected %s felt, got %s" - , expr, CronFieldType.values().length, parts.length)); + throw new IllegalArgumentException("expr is null"); //$NON-NLS-1$ } - this.secondField = new SimpleField(CronFieldType.SECOND, parts[0]); - this.minuteField = new SimpleField(CronFieldType.MINUTE, parts[1]); - this.hourField = new SimpleField(CronFieldType.HOUR, parts[2]); - this.dayOfMonthField = new DayOfMonthField(parts[3]); - this.monthField = new SimpleField(CronFieldType.MONTH, parts[4]); - this.dayOfWeekField = new DayOfWeekField(parts[5]); + this.expr = expr; + + final int expectedParts = withSeconds ? 6 : 5; + final String[] parts = expr.split("\\s+"); //$NON-NLS-1$ + if (parts.length != expectedParts) { + throw new IllegalArgumentException(String.format("Invalid cron expression [%s], expected %s felt, got %s" + , expr, expectedParts, parts.length)); + } + + int ix = withSeconds ? 1 : 0; + this.secondField = new SimpleField(CronFieldType.SECOND, withSeconds ? parts[0] : "*"); + this.minuteField = new SimpleField(CronFieldType.MINUTE, parts[ix++]); + this.hourField = new SimpleField(CronFieldType.HOUR, parts[ix++]); + this.dayOfMonthField = new DayOfMonthField(parts[ix++]); + this.monthField = new SimpleField(CronFieldType.MONTH, parts[ix++]); + this.dayOfWeekField = new DayOfWeekField(parts[ix++]); + } + + public static CronExpression create(final String expr) { + return new CronExpression(expr, true); + } + + public static CronExpression createWithoutSeconds(final String expr) { + return new CronExpression(expr, false); } public DateTime nextTimeAfter(DateTime afterTime) { @@ -465,6 +480,5 @@ public class CronExpression { protected boolean matches(int val, FieldPart part) { return "?".equals(part.modifier) || super.matches(val, part); } - } } diff --git a/src/test/java/fc/cron/CronExpressionTest.java b/src/test/java/fc/cron/CronExpressionTest.java index 9ffa43d..482fdea 100644 --- a/src/test/java/fc/cron/CronExpressionTest.java +++ b/src/test/java/fc/cron/CronExpressionTest.java @@ -466,4 +466,14 @@ public class CronExpressionTest { // The next leap year is 2016, so an IllegalArgumentException is expected. new CronExpression("* * * 29 2 *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00), 1000 * 60 * 60 * 24 * 356 * 2); } + + @Test(expected = IllegalArgumentException.class) + public void test_seconds_specified_but_should_be_omitted() throws Exception { + CronExpression.createWithoutSeconds("* * * 29 2 *"); + } + + @Test + public void test_without_seconds() throws Exception { + assertThat(CronExpression.createWithoutSeconds("* * 29 2 *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00))).isEqualTo(new DateTime(2016, 2, 29, 00, 00)); + } }