diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 40dff28..0000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Java CI - -on: [push] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@master - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - version: 11 - - name: Build with Maven - run: mvn package --file pom.xml diff --git a/.gitignore b/.gitignore index bcbe160..f3fc73f 100644 --- a/.gitignore +++ b/.gitignore @@ -217,3 +217,7 @@ pip-log.txt #Mr Developer .mr.developer.cfg *.class + +# IntelliJ +.idea/ +*.iml \ No newline at end of file diff --git a/README.md b/README.md index 50d1e38..9493aef 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,11 @@ -[![Known Vulnerabilities](https://snyk.io/test/github/frode-carlsen/cron/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/frode-carlsen/cron?targetFile=pom.xml) +Fork from https://github.com/set-de/cron # cron Cron expression parser and evaluator. Allows for specifying cron - expressions (in Unix or Quartz like format) and evaluating when it will next match. - -# Modules - * cron-jodatime: Based on jodatime. Supports java6 - * cron-java8: Based on java8/time. Requires java8+ # Usage diff --git a/java8/README.MD b/java8/README.MD deleted file mode 100644 index e8c8fc4..0000000 --- a/java8/README.MD +++ /dev/null @@ -1 +0,0 @@ -[![Known Vulnerabilities](https://snyk.io/test/github/frode-carlsen/cron/badge.svg?targetFile=java8%2Fpom.xml)](https://snyk.io/test/github/frode-carlsen/cron?targetFile=java8%2Fpom.xml) diff --git a/java8/pom.xml b/java8/pom.xml deleted file mode 100644 index c92eaf8..0000000 --- a/java8/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - 4.0.0 - - fc.cron - cron - 1.5 - - cron-java8 - jar - cron-java8 - - - - - maven-compiler-plugin - 3.8.1 - - true - 1.8 - 1.8 - UTF-8 - - - - maven-surefire-plugin - 2.22.2 - - - - - diff --git a/jodatime/README.MD b/jodatime/README.MD deleted file mode 100644 index 0c1de47..0000000 --- a/jodatime/README.MD +++ /dev/null @@ -1 +0,0 @@ -[![Known Vulnerabilities](https://snyk.io/test/github/frode-carlsen/cron/badge.svg?targetFile=jodatime%2Fpom.xml)](https://snyk.io/test/github/frode-carlsen/cron?targetFile=jodatime%2Fpom.xml) diff --git a/jodatime/pom.xml b/jodatime/pom.xml deleted file mode 100644 index 2756654..0000000 --- a/jodatime/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - 4.0.0 - - - - fc.cron - cron - 1.5 - - - cron-jodatime - jar - cron-jodatime - - - - joda-time - joda-time - 2.10.3 - - - org.assertj - assertj-core - 3.8.0 - test - - - - - - - - maven-compiler-plugin - 3.1 - - true - 1.7 - 1.7 - UTF-8 - - - - - - diff --git a/jodatime/src/main/java/fc/cron/CronExpression.java b/jodatime/src/main/java/fc/cron/CronExpression.java deleted file mode 100644 index a27c015..0000000 --- a/jodatime/src/main/java/fc/cron/CronExpression.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright (C) 2012 Frode Carlsen. - * - * 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 fc.cron; - -import static org.joda.time.DateTimeConstants.DAYS_PER_WEEK; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.MutableDateTime; - -/** - * This provides cron support for java6 upwards and jodatime. - *

- * - * 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 5 or 6 mandatory fields (seconds may be omitted) separated by space.
- * These are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Field Allowable values Special Characters
Seconds (may be omitted)  - * 0-59  - * , - * /
Minutes  - * 0-59  - * , - * /
Hours  - * 0-23  - * , - * /
Day of month  - * 1-31  - * , - * ? / L W
Month  - * 1-12 or JAN-DEC (note: english abbreviations)  - * , - * /
Day of week  - * 1-7 or MON-SUN (note: english abbreviations)  - * , - * ? / L #
- * - *

- * '*' Can be used in all fields and means 'for all values'. E.g. "*" in minutes, means 'for all minutes' - *

- * '?' Can be used in Day-of-month and Day-of-week fields. Used to signify 'no special value'. It is used when one want - * to specify something for one of those two fields, but not the other. - *

- * '-' Used to specify a time interval. E.g. "10-12" in Hours field means 'for hours 10, 11 and 12' - *

- * ',' Used to specify multiple values for a field. E.g. "MON,WED,FRI" in Day-of-week field means "for - * monday, wednesday and friday" - *

- * '/' Used to specify increments. E.g. "0/15" in Seconds field means "for seconds 0, 15, 30, ad - * 45". And "5/15" in seconds field means "for seconds 5, 20, 35, and 50". If '*' s specified - * before '/' it is the same as saying it starts at 0. For every field there's a list of values that can be turned on or - * off. For Seconds and Minutes these range from 0-59. For Hours from 0 to 23, For Day-of-month it's 1 to 31, For Months - * 1 to 12. "/" character helsp turn some of these values back on. Thus "7/6" in Months field - * specify just Month 7. It doesn't turn on every 6 month following, since cron fields never roll over - *

- * 'L' Can be used on Day-of-month and Day-of-week fields. It signifies last day of the set of allowed values. In - * Day-of-month field it's the last day of the month (e.g.. 31 jan, 28 feb (29 in leap years), 31 march, etc.). In - * Day-of-week field it's Sunday. If there's a prefix, this will be subtracted (5L in Day-of-month means 5 days before - * last day of Month: 26 jan, 23 feb, etc.) - *

- * 'W' Can be specified in Day-of-Month field. It specifies closest weekday (monday-friday). Holidays are not accounted - * for. "15W" in Day-of-Month field means 'closest weekday to 15 i in given month'. If the 15th is a Saturday, - * it gives Friday. If 15th is a Sunday, the it gives following Monday. - *

- * '#' Can be used in Day-of-Week field. For example: "5#3" means 'third friday in month' (day 5 = friday, #3 - * - the third). If the day does not exist (e.g. "5#5" - 5th friday of month) and there aren't 5 fridays in - * the month, then it won't match until the next month with 5 fridays. - *

- * Case-sensitive No fields are case-sensitive - *

- * Dependencies between fields Fields are always evaluated independently, but the expression doesn't match until - * the constraints of each field are met. Overlap of intervals are not allowed. That is: for - * Day-of-week field "FRI-MON" is invalid,but "FRI-SUN,MON" is valid - * - */ -public class CronExpression { - - enum CronFieldType { - SECOND(0, 59, null), - MINUTE(0, 59, null), - HOUR(0, 23, null), - DAY_OF_MONTH(1, 31, null), - MONTH(1, 12, Arrays.asList("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC")), - DAY_OF_WEEK(1, 7, Arrays.asList("MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN")); - - final int from, to; - final List names; - - CronFieldType(int from, int to, List names) { - this.from = from; - this.to = to; - this.names = names; - } - } - - private final String expr; - private final SimpleField secondField; - private final SimpleField minuteField; - private final SimpleField hourField; - private final DayOfWeekField dayOfWeekField; - private final SimpleField monthField; - private final DayOfMonthField dayOfMonthField; - - 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"); //$NON-NLS-1$ - } - - 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] : "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) { - // will search for the next time within the next 4 years. If there is no - // time matching, an InvalidArgumentException will be thrown (it is very - // likely that the cron expression is invalid, like the February 30th). - return nextTimeAfter(afterTime, afterTime.plusYears(4)); - } - - public DateTime nextTimeAfter(DateTime afterTime, long durationInMillis) { - // will search for the next time within the next durationInMillis - // millisecond. Be aware that the duration is specified in millis, - // but in fact the limit is checked on a day-to-day basis. - return nextTimeAfter(afterTime, afterTime.plus(durationInMillis)); - } - - public DateTime nextTimeAfter(DateTime afterTime, DateTime dateTimeBarrier) { - MutableDateTime nextTime = new MutableDateTime(afterTime); - nextTime.setMillisOfSecond(0); - nextTime.secondOfDay().add(1); - - while (true) { // day of week - while (true) { // month - while (true) { // day of month - while (true) { // hour - while (true) { // minute - while (true) { // second - if (secondField.matches(nextTime.getSecondOfMinute())) { - break; - } - nextTime.secondOfDay().add(1); - } - if (minuteField.matches(nextTime.getMinuteOfHour())) { - break; - } - nextTime.minuteOfDay().add(1); - nextTime.secondOfMinute().set(0); - } - if (hourField.matches(nextTime.getHourOfDay())) { - break; - } - nextTime.hourOfDay().add(1); - nextTime.minuteOfHour().set(0); - nextTime.secondOfMinute().set(0); - } - if (dayOfMonthField.matches(new LocalDate(nextTime))) { - break; - } - nextTime.addDays(1); - nextTime.setTime(0, 0, 0, 0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); - } - if (monthField.matches(nextTime.getMonthOfYear())) { - break; - } - nextTime.addMonths(1); - nextTime.setDayOfMonth(1); - nextTime.setTime(0, 0, 0, 0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); - } - if (dayOfWeekField.matches(new LocalDate(nextTime))) { - break; - } - nextTime.addDays(1); - nextTime.setTime(0, 0, 0, 0); - checkIfDateTimeBarrierIsReached(nextTime, dateTimeBarrier); - } - - return nextTime.toDateTime(); - } - - private static void checkIfDateTimeBarrierIsReached(MutableDateTime nextTime, DateTime dateTimeBarrier) { - if (nextTime.isAfter(dateTimeBarrier)) { - throw new IllegalArgumentException("No next execution time could be determined that is before the limit of " + dateTimeBarrier); - } - } - - @Override - public String toString() { - return getClass().getSimpleName() + "<" + expr + ">"; - } - - static class FieldPart { - private Integer from, to, increment; - private String modifier, incrementModifier; - } - - abstract static class BasicField { - private static final Pattern CRON_FIELD_REGEXP = Pattern - .compile("(?: # start of group 1\n" - + " (?:(\\*)|(\\?)|(L)) # global flag (L, ?, *)\n" - + " | ([0-9]{1,2}|[a-z]{3,3}) # or start number or symbol\n" - + " (?: # start of group 2\n" - + " (L|W) # modifier (L,W)\n" - + " | -([0-9]{1,2}|[a-z]{3,3}) # or end number or symbol (in range)\n" - + " )? # end of group 2\n" - + ") # end of group 1\n" - + "(?:(/|\\#)([0-9]{1,7}))? # increment and increment modifier (/ or \\#)\n" - , Pattern.CASE_INSENSITIVE | Pattern.COMMENTS); - - final CronFieldType fieldType; - final List parts = new ArrayList<>(); - - private BasicField(CronFieldType fieldType, String fieldExpr) { - this.fieldType = fieldType; - parse(fieldExpr); - } - - private void parse(String fieldExpr) { // NOSONAR - String[] rangeParts = fieldExpr.split(","); - for (String rangePart : rangeParts) { - Matcher m = CRON_FIELD_REGEXP.matcher(rangePart); - if (!m.matches()) { - throw new IllegalArgumentException("Invalid cron field '" + rangePart + "' for field [" + fieldType + "]"); - } - String startNumber = m.group(4); - String modifier = m.group(5); - String endNumber = m.group(6); - String incrementModifier = m.group(7); - String increment = m.group(8); - - FieldPart part = new FieldPart(); - part.increment = 999; - if (startNumber != null) { - part.from = mapValue(startNumber); - part.modifier = modifier; - if (endNumber != null) { - part.to = mapValue(endNumber); - part.increment = 1; - } else if (increment != null) { - part.to = fieldType.to; - } else { - part.to = part.from; - } - } else if (m.group(1) != null) { - part.from = fieldType.from; - part.to = fieldType.to; - part.increment = 1; - } else if (m.group(2) != null) { - part.modifier = m.group(2); - } else if (m.group(3) != null) { - part.modifier = m.group(3); - } else { - throw new IllegalArgumentException("Invalid cron part: " + rangePart); - } - - if (increment != null) { - part.incrementModifier = incrementModifier; - part.increment = Integer.valueOf(increment); - } - - validateRange(part); - validatePart(part); - parts.add(part); - - } - } - - protected void validatePart(FieldPart part) { - if (part.modifier != null) { - throw new IllegalArgumentException(String.format("Invalid modifier [%s]", part.modifier)); - } else if (part.incrementModifier != null && !"/".equals(part.incrementModifier)) { - throw new IllegalArgumentException(String.format("Invalid increment modifier [%s]", part.incrementModifier)); - } - } - - private void validateRange(FieldPart part) { - if ((part.from != null && part.from < fieldType.from) || (part.to != null && part.to > fieldType.to)) { - throw new IllegalArgumentException(String.format("Invalid interval [%s-%s], must be %s<=_<=%s", part.from, part.to, fieldType.from, - fieldType.to)); - } else if (part.from != null && part.to != null && part.from > part.to) { - throw new IllegalArgumentException( - String.format( - "Invalid interval [%s-%s]. Rolling periods are not supported (ex. 5-1, only 1-5) since this won't give a deterministic result. Must be %s<=_<=%s", - part.from, part.to, fieldType.from, fieldType.to)); - } - } - - protected Integer mapValue(String value) { - Integer idx; - if (fieldType.names != null && (idx = fieldType.names.indexOf(value.toUpperCase(Locale.getDefault()))) >= 0) { - return idx + 1; - } - return Integer.valueOf(value); - } - - protected boolean matches(int val, FieldPart part) { - if (val >= part.from && val <= part.to && (val - part.from) % part.increment == 0) { - return true; - } - return false; - } - } - - static class SimpleField extends BasicField { - SimpleField(CronFieldType fieldType, String fieldExpr) { - super(fieldType, fieldExpr); - } - - public boolean matches(int val) { - if (val >= fieldType.from && val <= fieldType.to) { - for (FieldPart part : parts) { - if (matches(val, part)) { - return true; - } - } - } - return false; - } - } - - static class DayOfWeekField extends BasicField { - - DayOfWeekField(String fieldExpr) { - super(CronFieldType.DAY_OF_WEEK, fieldExpr); - } - - boolean matches(LocalDate dato) { - for (FieldPart part : parts) { - if ("L".equals(part.modifier)) { - return dato.getDayOfWeek() == part.from && dato.getDayOfMonth() > (dato.dayOfMonth().getMaximumValue() - DAYS_PER_WEEK); - } else if ("#".equals(part.incrementModifier)) { - if (dato.getDayOfWeek() == part.from) { - int num = dato.getDayOfMonth() / 7; - return part.increment == (dato.getDayOfMonth() % 7 == 0 ? num : num + 1); - } - return false; - } else if (matches(dato.getDayOfWeek(), part)) { - return true; - } - } - return false; - } - - @Override - protected Integer mapValue(String value) { - // Use 1-7 for weedays, but 0 will also represent sunday (linux practice) - return "0".equals(value) ? Integer.valueOf(7) : super.mapValue(value); - } - - @Override - protected boolean matches(int val, FieldPart part) { - return "?".equals(part.modifier) || super.matches(val, part); - } - - @Override - protected void validatePart(FieldPart part) { - if (part.modifier != null && Arrays.asList("L", "?").indexOf(part.modifier) == -1) { - throw new IllegalArgumentException(String.format("Invalid modifier [%s]", part.modifier)); - } else if (part.incrementModifier != null && Arrays.asList("/", "#").indexOf(part.incrementModifier) == -1) { - throw new IllegalArgumentException(String.format("Invalid increment modifier [%s]", part.incrementModifier)); - } - } - } - - static class DayOfMonthField extends BasicField { - DayOfMonthField(String fieldExpr) { - super(CronFieldType.DAY_OF_MONTH, fieldExpr); - } - - boolean matches(LocalDate dato) { - for (FieldPart part : parts) { - if ("L".equals(part.modifier)) { - return dato.getDayOfMonth() == (dato.dayOfMonth().getMaximumValue() - (part.from == null ? 0 : part.from)); - } else if ("W".equals(part.modifier)) { - if (dato.getDayOfWeek() <= 5) { - if (dato.getDayOfMonth() == part.from) { - return true; - } else if (dato.getDayOfWeek() == 5) { - return dato.plusDays(1).getDayOfMonth() == part.from; - } else if (dato.getDayOfWeek() == 1) { - return dato.minusDays(1).getDayOfMonth() == part.from; - } - } - } else if (matches(dato.getDayOfMonth(), part)) { - return true; - } - } - return false; - } - - @Override - protected void validatePart(FieldPart part) { - if (part.modifier != null && Arrays.asList("L", "W", "?").indexOf(part.modifier) == -1) { - throw new IllegalArgumentException(String.format("Invalid modifier [%s]", part.modifier)); - } else if (part.incrementModifier != null && !"/".equals(part.incrementModifier)) { - throw new IllegalArgumentException(String.format("Invalid increment modifier [%s]", part.incrementModifier)); - } - } - - @Override - protected boolean matches(int val, FieldPart part) { - return "?".equals(part.modifier) || super.matches(val, part); - } - } -} diff --git a/jodatime/src/test/java/fc/cron/CronExpressionTest.java b/jodatime/src/test/java/fc/cron/CronExpressionTest.java deleted file mode 100644 index 46d7aa0..0000000 --- a/jodatime/src/test/java/fc/cron/CronExpressionTest.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2012- Frode Carlsen - * - * 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 fc.cron; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Hours; -import org.joda.time.LocalDate; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import fc.cron.CronExpression.CronFieldType; -import fc.cron.CronExpression.DayOfMonthField; -import fc.cron.CronExpression.DayOfWeekField; -import fc.cron.CronExpression.SimpleField; - -public class CronExpressionTest { - DateTimeZone original; - - @Before - public void setUp() { - original = DateTimeZone.getDefault(); - DateTimeZone.setDefault(DateTimeZone.forID("Europe/Oslo")); - } - - @After - public void tearDown() { - DateTimeZone.setDefault(original); - } - - @Test - public void shall_parse_number() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MINUTE, "5"); - assertPossibleValues(field, 5); - } - - private void assertPossibleValues(SimpleField field, Integer... values) { - Set valid = values == null ? new HashSet() : new HashSet<>(Arrays.asList(values)); - for (int i = field.fieldType.from; i <= field.fieldType.to; i++) { - String errorText = i + ":" + valid; - if (valid.contains(i)) { - assertThat(field.matches(i)).as(errorText).isTrue(); - } else { - assertThat(field.matches(i)).as(errorText).isFalse(); - } - } - } - - @Test - public void shall_parse_number_with_increment() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MINUTE, "0/15"); - assertPossibleValues(field, 0, 15, 30, 45); - } - - @Test - public void shall_parse_range() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MINUTE, "5-10"); - assertPossibleValues(field, 5, 6, 7, 8, 9, 10); - } - - @Test - public void shall_parse_range_with_increment() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MINUTE, "20-30/2"); - assertPossibleValues(field, 20, 22, 24, 26, 28, 30); - } - - @Test - public void shall_parse_asterix() throws Exception { - SimpleField field = new SimpleField(CronFieldType.DAY_OF_WEEK, "*"); - assertPossibleValues(field, 1, 2, 3, 4, 5, 6, 7); - } - - @Test - public void shall_parse_asterix_with_increment() throws Exception { - SimpleField field = new SimpleField(CronFieldType.DAY_OF_WEEK, "*/2"); - assertPossibleValues(field, 1, 3, 5, 7); - } - - @Test - public void shall_ignore_field_in_day_of_week() throws Exception { - DayOfWeekField field = new DayOfWeekField("?"); - assertThat(field.matches(new LocalDate())).isTrue(); - } - - @Test - public void shall_ignore_field_in_day_of_month() throws Exception { - DayOfMonthField field = new DayOfMonthField("?"); - assertThat(field.matches(new LocalDate())).isTrue(); - } - - @Test(expected = IllegalArgumentException.class) - public void shall_give_error_if_invalid_count_field() throws Exception { - new CronExpression("* 3 *"); - } - - @Test(expected = IllegalArgumentException.class) - public void shall_give_error_if_minute_field_ignored() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MINUTE, "?"); - field.matches(1); - } - - @Test(expected = IllegalArgumentException.class) - public void shall_give_error_if_hour_field_ignored() throws Exception { - SimpleField field = new SimpleField(CronFieldType.HOUR, "?"); - field.matches(1); - } - - @Test(expected = IllegalArgumentException.class) - public void shall_give_error_if_month_field_ignored() throws Exception { - SimpleField field = new SimpleField(CronFieldType.MONTH, "?"); - field.matches(1); - } - - @Test - public void shall_give_last_day_of_month_in_leapyear() throws Exception { - CronExpression.DayOfMonthField field = new DayOfMonthField("L"); - assertThat(field.matches(new LocalDate(2012, 02, 29))).isTrue(); - } - - @Test - public void shall_give_last_day_of_month() throws Exception { - CronExpression.DayOfMonthField field = new DayOfMonthField("L"); - assertThat(field.matches(new LocalDate().withDayOfMonth(new LocalDate().dayOfMonth().getMaximumValue()))).isTrue(); - } - - @Test - public void check_all() throws Exception { - assertThat(new CronExpression("* * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 01))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 02)); - assertThat(new CronExpression("* * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 02))).isEqualTo(new DateTime(2012, 4, 10, 13, 02, 01)); - assertThat(new CronExpression("* * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 59, 59))).isEqualTo(new DateTime(2012, 4, 10, 14, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void check_invalid_input() throws Exception { - new CronExpression(null); - } - - @Test - public void check_second_number() throws Exception { - assertThat(new CronExpression("3 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 01))).isEqualTo(new DateTime(2012, 4, 10, 13, 01, 03)); - assertThat(new CronExpression("3 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 01, 03))).isEqualTo(new DateTime(2012, 4, 10, 13, 02, 03)); - assertThat(new CronExpression("3 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 59, 03))).isEqualTo(new DateTime(2012, 4, 10, 14, 00, 03)); - assertThat(new CronExpression("3 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 23, 59, 03))).isEqualTo(new DateTime(2012, 4, 11, 00, 00, 03)); - assertThat(new CronExpression("3 * * * * *").nextTimeAfter(new DateTime(2012, 4, 30, 23, 59, 03))).isEqualTo(new DateTime(2012, 5, 01, 00, 00, 03)); - } - - @Test - public void check_second_increment() throws Exception { - assertThat(new CronExpression("5/15 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 05)); - assertThat(new CronExpression("5/15 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 05))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 20)); - assertThat(new CronExpression("5/15 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 20))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 35)); - assertThat(new CronExpression("5/15 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 35))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 50)); - assertThat(new CronExpression("5/15 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 50))).isEqualTo(new DateTime(2012, 4, 10, 13, 01, 05)); - - // if rolling over minute then reset second (cron rules - increment affects only values in own field) - assertThat(new CronExpression("10/100 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 50))) - .isEqualTo(new DateTime(2012, 4, 10, 13, 01, 10)); - assertThat(new CronExpression("10/100 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 01, 10))) - .isEqualTo(new DateTime(2012, 4, 10, 13, 02, 10)); - } - - @Test - public void check_second_list() throws Exception { - assertThat(new CronExpression("7,19 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 07)); - assertThat(new CronExpression("7,19 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 07))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 19)); - assertThat(new CronExpression("7,19 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 19))).isEqualTo(new DateTime(2012, 4, 10, 13, 01, 07)); - } - - @Test - public void check_second_range() throws Exception { - assertThat(new CronExpression("42-45 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 42)); - assertThat(new CronExpression("42-45 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 42))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 43)); - assertThat(new CronExpression("42-45 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 43))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 44)); - assertThat(new CronExpression("42-45 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 44))).isEqualTo(new DateTime(2012, 4, 10, 13, 00, 45)); - assertThat(new CronExpression("42-45 * * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00, 45))).isEqualTo(new DateTime(2012, 4, 10, 13, 01, 42)); - } - - @Test(expected = IllegalArgumentException.class) - public void check_second_invalid_range() throws Exception { - new CronExpression("42-63 * * * * *"); - } - - @Test(expected = IllegalArgumentException.class) - public void check_second_invalid_increment_modifier() throws Exception { - new CronExpression("42#3 * * * * *"); - } - - @Test - public void check_minute_number() throws Exception { - assertThat(new CronExpression("0 3 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 01))).isEqualTo(new DateTime(2012, 4, 10, 13, 03)); - assertThat(new CronExpression("0 3 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 03))).isEqualTo(new DateTime(2012, 4, 10, 14, 03)); - } - - @Test - public void check_minute_increment() throws Exception { - assertThat(new CronExpression("0 0/15 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 13, 15)); - assertThat(new CronExpression("0 0/15 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 15))).isEqualTo(new DateTime(2012, 4, 10, 13, 30)); - assertThat(new CronExpression("0 0/15 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 30))).isEqualTo(new DateTime(2012, 4, 10, 13, 45)); - assertThat(new CronExpression("0 0/15 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 45))).isEqualTo(new DateTime(2012, 4, 10, 14, 00)); - } - - @Test - public void check_minute_list() throws Exception { - assertThat(new CronExpression("0 7,19 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 13, 07)); - assertThat(new CronExpression("0 7,19 * * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 07))).isEqualTo(new DateTime(2012, 4, 10, 13, 19)); - } - - @Test - public void check_hour_number() throws Exception { - assertThat(new CronExpression("0 * 3 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 01))).isEqualTo(new DateTime(2012, 4, 11, 03, 00)); - assertThat(new CronExpression("0 * 3 * * *").nextTimeAfter(new DateTime(2012, 4, 11, 03, 00))).isEqualTo(new DateTime(2012, 4, 11, 03, 01)); - assertThat(new CronExpression("0 * 3 * * *").nextTimeAfter(new DateTime(2012, 4, 11, 03, 59))).isEqualTo(new DateTime(2012, 4, 12, 03, 00)); - } - - @Test - public void check_hour_increment() throws Exception { - assertThat(new CronExpression("0 * 0/15 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 15, 00)); - assertThat(new CronExpression("0 * 0/15 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 15, 00))).isEqualTo(new DateTime(2012, 4, 10, 15, 01)); - assertThat(new CronExpression("0 * 0/15 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 15, 59))).isEqualTo(new DateTime(2012, 4, 11, 00, 00)); - assertThat(new CronExpression("0 * 0/15 * * *").nextTimeAfter(new DateTime(2012, 4, 11, 00, 00))).isEqualTo(new DateTime(2012, 4, 11, 00, 01)); - assertThat(new CronExpression("0 * 0/15 * * *").nextTimeAfter(new DateTime(2012, 4, 11, 15, 00))).isEqualTo(new DateTime(2012, 4, 11, 15, 01)); - } - - @Test - public void check_hour_list() throws Exception { - assertThat(new CronExpression("0 * 7,19 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 10, 19, 00)); - assertThat(new CronExpression("0 * 7,19 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 19, 00))).isEqualTo(new DateTime(2012, 4, 10, 19, 01)); - assertThat(new CronExpression("0 * 7,19 * * *").nextTimeAfter(new DateTime(2012, 4, 10, 19, 59))).isEqualTo(new DateTime(2012, 4, 11, 07, 00)); - } - - @Test - public void check_hour_shall_run_25_times_in_DST_change_to_wintertime() throws Exception { - CronExpression cron = new CronExpression("0 1 * * * *"); - DateTime start = new DateTime(2011, 10, 30, 0, 0, 0, 0); - DateTime slutt = start.toLocalDate().plusDays(1).toDateTimeAtStartOfDay(); - DateTime tid = start; - assertThat(Hours.hoursBetween(start, slutt).getHours()).isEqualTo(25); - int count=0; - DateTime lastTime = tid; - while(tid.isBefore(slutt)){ - DateTime nextTime = cron.nextTimeAfter(tid); - assertThat(nextTime.isAfter(lastTime)).isTrue(); - lastTime = nextTime; - tid = tid.plusHours(1); - count++; - } - assertThat(count).isEqualTo(25); - } - - @Test - public void check_hour_shall_run_23_times_in_DST_change_to_summertime() throws Exception { - CronExpression cron = new CronExpression("0 0 * * * *"); - DateTime start = new DateTime(2011, 03, 27, 0, 0, 0, 0); - DateTime slutt = start.toLocalDate().plusDays(1).toDateTimeAtStartOfDay(); - DateTime tid = start; - assertThat(Hours.hoursBetween(start, slutt).getHours()).isEqualTo(23); - int count=0; - DateTime lastTime = tid; - while(tid.isBefore(slutt)){ - DateTime nextTime = cron.nextTimeAfter(tid); - assertThat(nextTime.isAfter(lastTime)).isTrue(); - lastTime = nextTime; - tid = tid.plusHours(1); - count++; - } - assertThat(count).isEqualTo(23); - } - - @Test - public void check_dayOfMonth_number() throws Exception { - assertThat(new CronExpression("0 * * 3 * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 5, 03, 00, 00)); - assertThat(new CronExpression("0 * * 3 * *").nextTimeAfter(new DateTime(2012, 5, 03, 00, 00))).isEqualTo(new DateTime(2012, 5, 03, 00, 01)); - assertThat(new CronExpression("0 * * 3 * *").nextTimeAfter(new DateTime(2012, 5, 03, 00, 59))).isEqualTo(new DateTime(2012, 5, 03, 01, 00)); - assertThat(new CronExpression("0 * * 3 * *").nextTimeAfter(new DateTime(2012, 5, 03, 23, 59))).isEqualTo(new DateTime(2012, 6, 03, 00, 00)); - } - - @Test - public void check_dayOfMonth_increment() throws Exception { - assertThat(new CronExpression("0 0 0 1/15 * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 16, 00, 00)); - assertThat(new CronExpression("0 0 0 1/15 * *").nextTimeAfter(new DateTime(2012, 4, 16, 00, 00))).isEqualTo(new DateTime(2012, 5, 01, 00, 00)); - assertThat(new CronExpression("0 0 0 1/15 * *").nextTimeAfter(new DateTime(2012, 4, 30, 00, 00))).isEqualTo(new DateTime(2012, 5, 01, 00, 00)); - assertThat(new CronExpression("0 0 0 1/15 * *").nextTimeAfter(new DateTime(2012, 5, 01, 00, 00))).isEqualTo(new DateTime(2012, 5, 16, 00, 00)); - } - - @Test - public void check_dayOfMonth_list() throws Exception { - assertThat(new CronExpression("0 0 0 7,19 * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 19, 00, 00)); - assertThat(new CronExpression("0 0 0 7,19 * *").nextTimeAfter(new DateTime(2012, 4, 19, 00, 00))).isEqualTo(new DateTime(2012, 5, 07, 00, 00)); - assertThat(new CronExpression("0 0 0 7,19 * *").nextTimeAfter(new DateTime(2012, 5, 07, 00, 00))).isEqualTo(new DateTime(2012, 5, 19, 00, 00)); - assertThat(new CronExpression("0 0 0 7,19 * *").nextTimeAfter(new DateTime(2012, 5, 30, 00, 00))).isEqualTo(new DateTime(2012, 6, 07, 00, 00)); - } - - @Test - public void check_dayOfMonth_last() throws Exception { - assertThat(new CronExpression("0 0 0 L * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 30, 00, 00)); - assertThat(new CronExpression("0 0 0 L * *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 2, 29, 00, 00)); - } - - @Test - public void check_dayOfMonth_number_last_L() throws Exception { - assertThat(new CronExpression("0 0 0 3L * *").nextTimeAfter(new DateTime(2012, 4, 10, 13, 00))).isEqualTo(new DateTime(2012, 4, 30 - 3, 00, 00)); - assertThat(new CronExpression("0 0 0 3L * *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 2, 29 - 3, 00, 00)); - } - - @Test - public void check_dayOfMonth_closest_weekday_W() throws Exception { - // 9 - is weekday in may - assertThat(new CronExpression("0 0 0 9W * *").nextTimeAfter(new DateTime(2012, 5, 2, 00, 00))).isEqualTo(new DateTime(2012, 5, 9, 00, 00)); - - // 9 - is weekday in may - assertThat(new CronExpression("0 0 0 9W * *").nextTimeAfter(new DateTime(2012, 5, 8, 00, 00))).isEqualTo(new DateTime(2012, 5, 9, 00, 00)); - - // 9 - saturday, friday closest weekday in june - assertThat(new CronExpression("0 0 0 9W * *").nextTimeAfter(new DateTime(2012, 5, 9, 00, 00))).isEqualTo(new DateTime(2012, 6, 8, 00, 00)); - - // 9 - sunday, monday closest weekday in september - assertThat(new CronExpression("0 0 0 9W * *").nextTimeAfter(new DateTime(2012, 9, 1, 00, 00))).isEqualTo(new DateTime(2012, 9, 10, 00, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void check_dayOfMonth_invalid_modifier() throws Exception { - new CronExpression("0 0 0 9X * *"); - } - - @Test(expected = IllegalArgumentException.class) - public void check_dayOfMonth_invalid_increment_modifier() throws Exception { - new CronExpression("0 0 0 9#2 * *"); - } - - @Test - public void check_month_number() throws Exception { - assertThat(new CronExpression("0 0 0 1 5 *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 5, 1, 00, 00)); - } - - @Test - public void check_month_increment() throws Exception { - assertThat(new CronExpression("0 0 0 1 5/2 *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 5, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 1 5/2 *").nextTimeAfter(new DateTime(2012, 5, 1, 00, 00))).isEqualTo(new DateTime(2012, 7, 1, 00, 00)); - - // if rolling over year then reset month field (cron rules - increments only affect own field) - assertThat(new CronExpression("0 0 0 1 5/10 *").nextTimeAfter(new DateTime(2012, 5, 1, 00, 00))).isEqualTo(new DateTime(2013, 5, 1, 00, 00)); - } - - @Test - public void check_month_list() throws Exception { - assertThat(new CronExpression("0 0 0 1 3,7,12 *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 3, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 1 3,7,12 *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00))).isEqualTo(new DateTime(2012, 7, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 1 3,7,12 *").nextTimeAfter(new DateTime(2012, 7, 1, 00, 00))).isEqualTo(new DateTime(2012, 12, 1, 00, 00)); - } - - @Test - public void check_month_list_by_name() throws Exception { - assertThat(new CronExpression("0 0 0 1 MAR,JUL,DEC *").nextTimeAfter(new DateTime(2012, 2, 12, 00, 00))).isEqualTo(new DateTime(2012, 3, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 1 MAR,JUL,DEC *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00))).isEqualTo(new DateTime(2012, 7, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 1 MAR,JUL,DEC *").nextTimeAfter(new DateTime(2012, 7, 1, 00, 00))).isEqualTo(new DateTime(2012, 12, 1, 00, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void check_month_invalid_modifier() throws Exception { - new CronExpression("0 0 0 1 ? *"); - } - - @Test - public void check_dayOfWeek_number() throws Exception { - assertThat(new CronExpression("0 0 0 * * 3").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 4, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3").nextTimeAfter(new DateTime(2012, 4, 4, 00, 00))).isEqualTo(new DateTime(2012, 4, 11, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3").nextTimeAfter(new DateTime(2012, 4, 12, 00, 00))).isEqualTo(new DateTime(2012, 4, 18, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3").nextTimeAfter(new DateTime(2012, 4, 18, 00, 00))).isEqualTo(new DateTime(2012, 4, 25, 00, 00)); - } - - @Test - public void check_dayOfWeek_increment() throws Exception { - assertThat(new CronExpression("0 0 0 * * 3/2").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 4, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3/2").nextTimeAfter(new DateTime(2012, 4, 4, 00, 00))).isEqualTo(new DateTime(2012, 4, 6, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3/2").nextTimeAfter(new DateTime(2012, 4, 6, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3/2").nextTimeAfter(new DateTime(2012, 4, 8, 00, 00))).isEqualTo(new DateTime(2012, 4, 11, 00, 00)); - } - - @Test - public void check_dayOfWeek_list() throws Exception { - assertThat(new CronExpression("0 0 0 * * 1,5,7").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 2, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 1,5,7").nextTimeAfter(new DateTime(2012, 4, 2, 00, 00))).isEqualTo(new DateTime(2012, 4, 6, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 1,5,7").nextTimeAfter(new DateTime(2012, 4, 6, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - } - - @Test - public void check_dayOfWeek_list_by_name() throws Exception { - assertThat(new CronExpression("0 0 0 * * MON,FRI,SUN").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 2, 00, 00)); - assertThat(new CronExpression("0 0 0 * * MON,FRI,SUN").nextTimeAfter(new DateTime(2012, 4, 2, 00, 00))).isEqualTo(new DateTime(2012, 4, 6, 00, 00)); - assertThat(new CronExpression("0 0 0 * * MON,FRI,SUN").nextTimeAfter(new DateTime(2012, 4, 6, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - } - - @Test - public void check_dayOfWeek_last_friday_in_month() throws Exception { - assertThat(new CronExpression("0 0 0 * * 5L").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 27, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 5L").nextTimeAfter(new DateTime(2012, 4, 27, 00, 00))).isEqualTo(new DateTime(2012, 5, 25, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 5L").nextTimeAfter(new DateTime(2012, 2, 6, 00, 00))).isEqualTo(new DateTime(2012, 2, 24, 00, 00)); - assertThat(new CronExpression("0 0 0 * * FRIL").nextTimeAfter(new DateTime(2012, 2, 6, 00, 00))).isEqualTo(new DateTime(2012, 2, 24, 00, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void check_dayOfWeek_invalid_modifier() throws Exception { - new CronExpression("0 0 0 * * 5W"); - } - - @Test(expected = IllegalArgumentException.class) - public void check_dayOfWeek_invalid_increment_modifier() throws Exception { - new CronExpression("0 0 0 * * 5?3"); - } - - @Test - public void check_dayOfWeek_shall_interpret_0_as_sunday() throws Exception { - assertThat(new CronExpression("0 0 0 * * 0").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 0L").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 29, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 0#2").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - } - - @Test - public void check_dayOfWeek_shall_interpret_7_as_sunday() throws Exception { - assertThat(new CronExpression("0 0 0 * * 7").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 7L").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 29, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 7#2").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 8, 00, 00)); - } - - @Test - public void check_dayOfWeek_nth_friday_in_month() throws Exception { - assertThat(new CronExpression("0 0 0 * * 5#3").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 4, 20, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 5#3").nextTimeAfter(new DateTime(2012, 4, 20, 00, 00))).isEqualTo(new DateTime(2012, 5, 18, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 7#1").nextTimeAfter(new DateTime(2012, 3, 30, 00, 00))).isEqualTo(new DateTime(2012, 4, 1, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 7#1").nextTimeAfter(new DateTime(2012, 4, 1, 00, 00))).isEqualTo(new DateTime(2012, 5, 6, 00, 00)); - assertThat(new CronExpression("0 0 0 * * 3#5").nextTimeAfter(new DateTime(2012, 2, 6, 00, 00))).isEqualTo(new DateTime(2012, 2, 29, 00, 00)); // leapday - assertThat(new CronExpression("0 0 0 * * WED#5").nextTimeAfter(new DateTime(2012, 2, 6, 00, 00))).isEqualTo(new DateTime(2012, 2, 29, 00, 00)); // leapday - } - - @Test(expected = IllegalArgumentException.class) - public void shall_not_not_support_rolling_period() throws Exception { - new CronExpression("* * 5-1 * * *"); - } - - @Test(expected = IllegalArgumentException.class) - public void non_existing_date_throws_exception() throws Exception { - // Will check for the next 4 years - no 30th of February is found so a IAE is thrown. - new CronExpression("* * * 30 2 *").nextTimeAfter(DateTime.now()); - } - - @Test - public void test_default_barrier() throws Exception { - // the default barrier is 4 years - so leap years are considered. - assertThat(new CronExpression("* * * 29 2 *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00))).isEqualTo(new DateTime(2016, 2, 29, 00, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void test_one_year_barrier() throws Exception { - // The next leap year is 2016, so an IllegalArgumentException is expected. - new CronExpression("* * * 29 2 *").nextTimeAfter(new DateTime(2012, 3, 1, 00, 00), new DateTime(2013, 3, 1, 00, 00)); - } - - @Test(expected = IllegalArgumentException.class) - public void test_two_year_barrier() throws Exception { - // 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)); - } -} diff --git a/pom.xml b/pom.xml index 79d366b..690bd71 100644 --- a/pom.xml +++ b/pom.xml @@ -1,85 +1,89 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 - fc.cron - cron - pom - 1.5 - cron - https://github.com/frode-carlsen/cron - - - - Apache License Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 - - + fc.cron + 1.5 + jar + cron-java8 + cron-java8 + https://github.com/eitch/cron + + + UTF-8 + UTF-8 + - - java8 - jodatime - + + + Apache License Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + + + + maven-compiler-plugin + 3.8.1 + + true + 1.8 + 1.8 + UTF-8 + + + + maven-surefire-plugin + 2.22.2 + + + - - - junit - junit - 4.12 - test - - + + + junit + junit + 4.12 + test + + - - - release - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + + + + - - - - - - UTF-8 - UTF-8 - diff --git a/java8/src/main/java/fc/cron/CronExpression.java b/src/main/java/fc/cron/CronExpression.java similarity index 100% rename from java8/src/main/java/fc/cron/CronExpression.java rename to src/main/java/fc/cron/CronExpression.java diff --git a/java8/src/test/java/fc/cron/CronExpressionTest.java b/src/test/java/fc/cron/CronExpressionTest.java similarity index 100% rename from java8/src/test/java/fc/cron/CronExpressionTest.java rename to src/test/java/fc/cron/CronExpressionTest.java