Example #1
0
  /**
   * If date is not match, will return previous closest match. If date is match, will return this
   * date.
   *
   * @param date - reference DateTime instance - never null;
   * @return DateTime instance, never null. Value obeys logic specified above.
   * @throws NoSuchValueException
   */
  DateTime previousClosestMatch(DateTime date) throws NoSuchValueException {
    List<Integer> year = yearsValueGenerator.generateCandidates(date.getYear(), date.getYear());
    TimeNode days = generateDays(cronDefinition, date);
    int highestMonth = months.getValues().get(months.getValues().size() - 1);
    int highestDay = days.getValues().get(days.getValues().size() - 1);
    int highestHour = hours.getValues().get(hours.getValues().size() - 1);
    int highestMinute = minutes.getValues().get(minutes.getValues().size() - 1);
    int highestSecond = seconds.getValues().get(seconds.getValues().size() - 1);

    NearestValue nearestValue;
    DateTime newDate;
    if (year.isEmpty()) {
      int previousYear = yearsValueGenerator.generatePreviousValue(date.getYear());
      if (highestDay > 28) {
        int highestDayOfMonth =
            new DateTime(previousYear, highestMonth, 1, 0, 0).dayOfMonth().getMaximumValue();
        if (highestDay > highestDayOfMonth) {
          nearestValue = days.getPreviousValue(highestDay, 1);
          if (nearestValue.getShifts() > 0) {
            newDate =
                new DateTime(previousYear, highestMonth, 1, 23, 59, 59, date.getZone())
                    .minusMonths(nearestValue.getShifts())
                    .dayOfMonth()
                    .withMaximumValue();
            return previousClosestMatch(newDate);
          } else {
            highestDay = nearestValue.getValue();
          }
        }
      }
      return initDateTime(
          previousYear,
          highestMonth,
          highestDay,
          highestHour,
          highestMinute,
          highestSecond,
          date.getZone());
    }
    if (!months.getValues().contains(date.getMonthOfYear())) {
      nearestValue = months.getPreviousValue(date.getMonthOfYear(), 0);
      int previousMonths = nearestValue.getValue();
      if (nearestValue.getShifts() > 0) {
        newDate =
            new DateTime(date.getYear(), 12, 31, 23, 59, 59, date.getZone())
                .minusYears(nearestValue.getShifts());
        return previousClosestMatch(newDate);
      }
      return initDateTime(
          date.getYear(),
          previousMonths,
          highestDay,
          highestHour,
          highestMinute,
          highestSecond,
          date.getZone());
    }
    if (!days.getValues().contains(date.getDayOfMonth())) {
      nearestValue = days.getPreviousValue(date.getDayOfMonth(), 0);
      if (nearestValue.getShifts() > 0) {
        newDate =
            new DateTime(date.getYear(), date.getMonthOfYear(), 1, 23, 59, 59, date.getZone())
                .minusMonths(nearestValue.getShifts())
                .dayOfMonth()
                .withMaximumValue();
        return previousClosestMatch(newDate);
      }
      return initDateTime(
          date.getYear(),
          date.getMonthOfYear(),
          nearestValue.getValue(),
          highestHour,
          highestMinute,
          highestSecond,
          date.getZone());
    }
    if (!hours.getValues().contains(date.getHourOfDay())) {
      nearestValue = hours.getPreviousValue(date.getHourOfDay(), 0);
      if (nearestValue.getShifts() > 0) {
        newDate =
            new DateTime(
                    date.getYear(),
                    date.getMonthOfYear(),
                    date.getDayOfMonth(),
                    23,
                    59,
                    59,
                    date.getZone())
                .minusDays(nearestValue.getShifts());
        return previousClosestMatch(newDate);
      }
      return initDateTime(
          date.getYear(),
          date.getMonthOfYear(),
          date.getDayOfMonth(),
          nearestValue.getValue(),
          highestMinute,
          highestSecond,
          date.getZone());
    }
    if (!minutes.getValues().contains(date.getMinuteOfHour())) {
      nearestValue = minutes.getPreviousValue(date.getMinuteOfHour(), 0);
      if (nearestValue.getShifts() > 0) {
        newDate =
            new DateTime(
                    date.getYear(),
                    date.getMonthOfYear(),
                    date.getDayOfMonth(),
                    date.getHourOfDay(),
                    59,
                    59,
                    date.getZone())
                .minusHours(nearestValue.getShifts());
        return previousClosestMatch(newDate);
      }
      return initDateTime(
          date.getYear(),
          date.getMonthOfYear(),
          date.getDayOfMonth(),
          date.getHourOfDay(),
          nearestValue.getValue(),
          highestSecond,
          date.getZone());
    }
    if (!seconds.getValues().contains(date.getSecondOfMinute())) {
      nearestValue = seconds.getPreviousValue(date.getSecondOfMinute(), 0);
      int previousSeconds = nearestValue.getValue();
      if (nearestValue.getShifts() > 0) {
        newDate =
            new DateTime(
                    date.getYear(),
                    date.getMonthOfYear(),
                    date.getDayOfMonth(),
                    date.getHourOfDay(),
                    date.getMinuteOfHour(),
                    59,
                    date.getZone())
                .minusMinutes(nearestValue.getShifts());
        return previousClosestMatch(newDate);
      }
      return initDateTime(
          date.getYear(),
          date.getMonthOfYear(),
          date.getDayOfMonth(),
          date.getHourOfDay(),
          date.getMinuteOfHour(),
          previousSeconds,
          date.getZone());
    }
    return date;
  }