Пример #1
0
  /**
   * Returns the the next date of this recurrence given a seed date and start date. The seed date
   * indicates the start of the fist occurrence of this recurrence. The start date is the starting
   * date to search for the next recurrence. Return null if there is no occurrence date after start
   * date.
   *
   * @return the next date in the recurrence series after startDate
   * @param seed the start date of this Recurrence's first instance
   * @param startDate the date to start the search
   */
  public final Date getNextDate(final Date seed, final Date startDate) {

    final Calendar cal = Dates.getCalendarInstance(seed);
    cal.setTime(seed);

    // optimize the start time for selecting candidates
    // (only applicable where a COUNT is not specified)
    if (getCount() < 1) {
      final Calendar seededCal = (Calendar) cal.clone();
      while (seededCal.getTime().before(startDate)) {
        cal.setTime(seededCal.getTime());
        increment(seededCal);
      }
    }

    int invalidCandidateCount = 0;
    int noCandidateIncrementCount = 0;
    Date candidate = null;
    final Value value = seed instanceof DateTime ? Value.DATE_TIME : Value.DATE;

    while (true) {
      final Date candidateSeed = Dates.getInstance(cal.getTime(), value);

      if (getUntil() != null && candidate != null && candidate.after(getUntil())) {
        break;
      }

      if (getCount() > 0 && invalidCandidateCount >= getCount()) {
        break;
      }

      if (Value.DATE_TIME.equals(value)) {
        if (((DateTime) seed).isUtc()) {
          ((DateTime) candidateSeed).setUtc(true);
        } else {
          ((DateTime) candidateSeed).setTimeZone(((DateTime) seed).getTimeZone());
        }
      }

      final DateList candidates = getCandidates(candidateSeed, value);
      if (!candidates.isEmpty()) {
        noCandidateIncrementCount = 0;
        // sort candidates for identifying when UNTIL date is exceeded..
        Collections.sort(candidates);

        for (final Iterator<Date> i = candidates.iterator(); i.hasNext(); ) {
          candidate = i.next();
          // don't count candidates that occur before the seed date..
          if (!candidate.before(seed)) {
            // Candidate must be after startDate because
            // we want the NEXT occurrence
            if (!candidate.after(startDate)) {
              invalidCandidateCount++;
            } else if (getCount() > 0 && invalidCandidateCount >= getCount()) {
              break;
            } else if (!(getUntil() != null && candidate.after(getUntil()))) {
              return candidate;
            }
          }
        }
      } else {
        noCandidateIncrementCount++;
        if ((maxIncrementCount > 0) && (noCandidateIncrementCount > maxIncrementCount)) {
          break;
        }
      }
      increment(cal);
    }
    return null;
  }
Пример #2
0
  /**
   * Returns a list of start dates in the specified period represented by this recur. This method
   * includes a base date argument, which indicates the start of the fist occurrence of this
   * recurrence. The base date is used to inject default values to return a set of dates in the
   * correct format. For example, if the search start date (start) is Wed, Mar 23, 12:19PM, but the
   * recurrence is Mon - Fri, 9:00AM - 5:00PM, the start dates returned should all be at 9:00AM, and
   * not 12:19PM.
   *
   * @return a list of dates represented by this recur instance
   * @param seed the start date of this Recurrence's first instance
   * @param periodStart the start of the period
   * @param periodEnd the end of the period
   * @param value the type of dates to generate (i.e. date/date-time)
   * @param maxCount limits the number of instances returned. Up to one years worth extra may be
   *     returned. Less than 0 means no limit
   */
  public final DateList getDates(
      final Date seed,
      final Date periodStart,
      final Date periodEnd,
      final Value value,
      final int maxCount) {

    final DateList dates = new DateList(value);
    if (seed instanceof DateTime) {
      if (((DateTime) seed).isUtc()) {
        dates.setUtc(true);
      } else {
        dates.setTimeZone(((DateTime) seed).getTimeZone());
      }
    }
    final Calendar cal = Dates.getCalendarInstance(seed);
    cal.setTime(seed);

    // optimize the start time for selecting candidates
    // (only applicable where a COUNT is not specified)
    if (getCount() < 1) {
      final Calendar seededCal = (Calendar) cal.clone();
      while (seededCal.getTime().before(periodStart)) {
        cal.setTime(seededCal.getTime());
        increment(seededCal);
      }
    }

    int invalidCandidateCount = 0;
    int noCandidateIncrementCount = 0;
    Date candidate = null;
    while ((maxCount < 0) || (dates.size() < maxCount)) {
      final Date candidateSeed = Dates.getInstance(cal.getTime(), value);

      if (getUntil() != null && candidate != null && candidate.after(getUntil())) {

        break;
      }
      if (periodEnd != null && candidate != null && candidate.after(periodEnd)) {

        break;
      }
      if (getCount() >= 1 && (dates.size() + invalidCandidateCount) >= getCount()) {

        break;
      }

      //            if (Value.DATE_TIME.equals(value)) {
      if (candidateSeed instanceof DateTime) {
        if (dates.isUtc()) {
          ((DateTime) candidateSeed).setUtc(true);
        } else {
          ((DateTime) candidateSeed).setTimeZone(dates.getTimeZone());
        }
      }

      final DateList candidates = getCandidates(candidateSeed, value);
      if (!candidates.isEmpty()) {
        noCandidateIncrementCount = 0;
        // sort candidates for identifying when UNTIL date is exceeded..
        Collections.sort(candidates);
        for (final Iterator<Date> i = candidates.iterator(); i.hasNext(); ) {
          candidate = i.next();
          // don't count candidates that occur before the seed date..
          if (!candidate.before(seed)) {
            // candidates exclusive of periodEnd..
            if (candidate.before(periodStart) || !candidate.before(periodEnd)) {
              invalidCandidateCount++;
            } else if (getCount() >= 1 && (dates.size() + invalidCandidateCount) >= getCount()) {
              break;
            } else if (!(getUntil() != null && candidate.after(getUntil()))) {
              dates.add(candidate);
            }
          }
        }
      } else {
        noCandidateIncrementCount++;
        if ((maxIncrementCount > 0) && (noCandidateIncrementCount > maxIncrementCount)) {
          break;
        }
      }
      increment(cal);
    }
    // sort final list..
    Collections.sort(dates);
    return dates;
  }