private static boolean keepCurrent(Calendar asOfDate) {
    boolean keepCurrent = false;

    int monthNow = asOfDate.get(Calendar.MONTH);

    // March, June, September, and December are expiration months
    boolean isExpirationMonth = ((monthNow + 1) % 3 == 0);

    if (isExpirationMonth) {
      Calendar volumeShiftDate = (Calendar) asOfDate.clone();

      // Find first Friday
      volumeShiftDate.set(Calendar.DAY_OF_MONTH, 1);
      while (volumeShiftDate.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY) {
        volumeShiftDate.add(Calendar.DAY_OF_MONTH, 1);
      }

      // Shift to third Friday
      volumeShiftDate.add(Calendar.WEEK_OF_MONTH, 2);

      // Finally, find the day before second Friday
      volumeShiftDate.add(Calendar.DAY_OF_MONTH, -8);

      if (asOfDate.before(volumeShiftDate)) {
        keepCurrent = true;
      }
    }

    return keepCurrent;
  }
Beispiel #2
0
  /**
   * Finds the next occurrence for monthly Nth recurrence.
   *
   * @param startDate the start date of the previous calendar item.
   * @param endDate the end date of the previous calendar item.
   * @return the next item
   */
  public CalendarItemTimerTask nextMonthN(Date startDate, Date endDate) {
    int dayOfWeekInMonth = (patternSpecific2 == 5 ? -1 : patternSpecific2);
    long duration = sourceTask.getEndDate().getTime() - sourceTask.getStartDate().getTime();
    Calendar cal = Calendar.getInstance();
    cal.setTime(startDate);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    cal.add(Calendar.MONTH, period);
    cal.setTime(getMonthNStartDate(cal.getTime(), dayOfWeekInMonth));
    Date currentDate = new Date();
    if (cal.getTimeInMillis() + duration < currentDate.getTime()) {
      Calendar cal2 = Calendar.getInstance();
      cal2.setTime(currentDate);
      int years = cal2.get(Calendar.YEAR) - cal.get(Calendar.YEAR);
      int months = (years * 12) + (cal2.get(Calendar.MONTH) - cal.get(Calendar.MONTH));
      int monthsToAdd = months;
      monthsToAdd -= months % period;
      cal.set(Calendar.DAY_OF_MONTH, 1);
      cal.add(Calendar.MONTH, monthsToAdd);
      cal.setTime(getMonthNStartDate(cal.getTime(), dayOfWeekInMonth));
      if (cal.getTimeInMillis() + duration < currentDate.getTime()) {
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, monthsToAdd);
        cal.setTime(getMonthNStartDate(cal.getTime(), dayOfWeekInMonth));
      }
    }

    Calendar cal2 = (Calendar) cal.clone();
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    while (deletedInstances.contains(cal.getTime())) {
      cal.set(Calendar.DAY_OF_MONTH, 1);
      cal.add(Calendar.MONTH, period);
      startDate = null;
      for (int dayOfWeek : allowedDaysOfWeek) {
        cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, dayOfWeekInMonth);
        if ((cal.after(startDate) && dayOfWeekInMonth == -1)
            || (cal.before(startDate) && dayOfWeekInMonth != -1)
            || startDate == null) {
          startDate = cal.getTime();
          cal2.set(Calendar.YEAR, cal.get(Calendar.YEAR));
          cal2.set(Calendar.MONTH, cal.get(Calendar.MONTH));
          cal2.set(Calendar.DATE, cal.get(Calendar.DATE));
        }
      }
    }

    startDate = cal2.getTime();
    endDate = new Date(startDate.getTime() + duration);

    if (dateOutOfRange(endDate)) return null;

    boolean executeNow = false;
    if (startDate.before(currentDate)) {
      executeNow = true;
    }

    return new CalendarItemTimerTask(
        sourceTask.getStatus(), startDate, endDate, sourceTask.getId(), executeNow, this);
  }