public void testSubDailyFreqs() throws ParseException {
    task.setValue(Task.DUE_DATE, DateUtilities.now() - DateUtilities.ONE_WEEK);
    task.setFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION, true);

    for (Frequency freq : Frequency.values()) {
      long interval = -1;
      switch (freq) {
        case MINUTELY:
          interval = DateUtilities.ONE_MINUTE;
          break;
        case HOURLY:
          interval = DateUtilities.ONE_HOUR;
          break;
        default:
          continue;
      }

      buildRRule(1, freq);
      nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());

      buildRRule(6, freq);
      nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
      assertDateTimeEquals(freq.toString() + "x6", DateUtilities.now() + 6 * interval, nextDueDate);
      task.setValue(Task.DUE_DATE, nextDueDate);
      assertTrue(task.hasDueTime());
    }
  }
  /** Initialize RRule instance */
  private static RRule initRRule(String recurrence) throws ParseException {
    RRule rrule = new RRule(recurrence);

    // handle the iCalendar "byDay" field differently depending on if
    // we are weekly or otherwise
    if (rrule.getFreq() != Frequency.WEEKLY) rrule.setByDay(Collections.EMPTY_LIST);

    return rrule;
  }
 static long handleSubdayRepeat(DateTime startDate, RRule rrule) {
   long millis;
   switch (rrule.getFreq()) {
     case HOURLY:
       millis = DateUtilities.ONE_HOUR;
       break;
     case MINUTELY:
       millis = DateUtilities.ONE_MINUTE;
       break;
     default:
       throw new RuntimeException(
           "Error handing subday repeat: " + rrule.getFreq()); // $NON-NLS-1$
   }
   long newDueDate = startDate.getMillis() + millis * rrule.getInterval();
   return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDueDate);
 }
  public void testDailyAndGreaterFreqs() throws ParseException {
    task.setValue(
        Task.DUE_DATE,
        Task.createDueDate(
            Task.URGENCY_SPECIFIC_DAY, DateUtilities.now() - DateUtilities.ONE_WEEK));
    task.setFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION, true);

    for (int interval = 1; interval < 7; interval++) {
      for (Frequency freq : Frequency.values()) {
        long next = DateUtilities.now();
        switch (freq) {
          case DAILY:
            next += interval * DateUtilities.ONE_DAY;
            break;
          case WEEKLY:
            next += interval * DateUtilities.ONE_WEEK;
            break;
          case MONTHLY:
            next = DateUtilities.addCalendarMonthsToUnixtime(next, interval);
            break;
          case YEARLY:
            next = DateUtilities.addCalendarMonthsToUnixtime(next, interval * 12);
            break;
          default:
            continue;
        }

        buildRRule(interval, freq);
        nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
        assertDateEquals(freq.toString() + "x" + interval, next, nextDueDate);
        task.setValue(Task.DUE_DATE, nextDueDate);
        assertFalse(task.hasDueTime());
      }
    }
  }
  public void testTimeZoneLate() throws ParseException {
    TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
    task.setValue(Task.DUE_DATE, DateUtilities.now() + DateUtilities.ONE_WEEK);
    task.setFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION, true);
    nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());

    long expected = Task.createDueDate(Task.URGENCY_TOMORROW, 0);
    assertDateEquals("tomorrow", expected, nextDueDate);
  }
Пример #6
0
  // Parses through the text and sets the frequency of the task.
  private static boolean repeatHelper(Task task) {
    if (task.containsNonNullValue(Task.RECURRENCE)) {
      return false;
    }
    String inputText = task.getValue(Task.TITLE);
    HashMap<String, Frequency> repeatTimes = new HashMap<String, Frequency>();
    repeatTimes.put("(?i)\\bevery ?\\w{0,6} days?\\b", Frequency.DAILY);
    repeatTimes.put("(?i)\\bevery ?\\w{0,6} ?nights?\\b", Frequency.DAILY);
    repeatTimes.put("(?i)\\bevery ?\\w{0,6} ?mornings?\\b", Frequency.DAILY);
    repeatTimes.put("(?i)\\bevery ?\\w{0,6} ?evenings?\\b", Frequency.DAILY);
    repeatTimes.put("(?i)\\bevery ?\\w{0,6} ?afternoons?\\b", Frequency.DAILY);
    repeatTimes.put("(?i)\\bevery \\w{0,6} ?weeks?\\b", Frequency.WEEKLY);
    repeatTimes.put(
        "(?i)\\bevery \\w{0,6} ?(mon|tues|wednes|thurs|fri|satur|sun)days?\\b", Frequency.WEEKLY);
    repeatTimes.put("(?i)\\bevery \\w{0,6} ?months?\\b", Frequency.MONTHLY);
    repeatTimes.put("(?i)\\bevery \\w{0,6} ?years?\\b", Frequency.YEARLY);

    HashMap<String, Frequency> repeatTimesIntervalOne = new HashMap<String, Frequency>();
    // pre-determined intervals of 1
    repeatTimesIntervalOne.put("(?i)\\bdaily\\b", Frequency.DAILY);
    repeatTimesIntervalOne.put("(?i)\\beveryday\\b", Frequency.DAILY);
    repeatTimesIntervalOne.put("(?i)\\bweekly\\b", Frequency.WEEKLY);
    repeatTimesIntervalOne.put("(?i)\\bmonthly\\b", Frequency.MONTHLY);
    repeatTimesIntervalOne.put("(?i)\\byearly\\b", Frequency.YEARLY);

    Set<String> keys = repeatTimes.keySet();
    for (String repeatTime : keys) {
      Pattern pattern = Pattern.compile(repeatTime);
      Matcher m = pattern.matcher(inputText);
      if (m.find()) {
        Frequency rtime = repeatTimes.get(repeatTime);
        RRule rrule = new RRule();
        rrule.setFreq(rtime);
        rrule.setInterval(findInterval(inputText));
        task.setValue(Task.RECURRENCE, rrule.toIcal());
        return true;
      }
    }

    for (String repeatTimeIntervalOne : repeatTimesIntervalOne.keySet()) {
      Pattern pattern = Pattern.compile(repeatTimeIntervalOne);
      Matcher m = pattern.matcher(inputText);
      if (m.find()) {
        Frequency rtime = repeatTimesIntervalOne.get(repeatTimeIntervalOne);
        RRule rrule = new RRule();
        rrule.setFreq(rtime);
        rrule.setInterval(1);
        String thing = rrule.toIcal();
        task.setValue(Task.RECURRENCE, thing);
        return true;
      }
    }
    return false;
  }
  private static long handleWeeklyRepeatAfterComplete(
      RRule rrule, Date original, boolean hasDueTime) {
    List<WeekdayNum> byDay = rrule.getByDay();
    long newDate = original.getTime();
    newDate += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
    Calendar date = Calendar.getInstance();
    date.setTimeInMillis(newDate);

    Collections.sort(byDay, weekdayCompare);
    WeekdayNum next = findNextWeekday(byDay, date);

    do {
      date.add(Calendar.DATE, 1);
    } while (date.get(Calendar.DAY_OF_WEEK) != next.wday.javaDayNum);

    long time = date.getTimeInMillis();
    if (hasDueTime) return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
    else return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
  }
Пример #8
0
 public DateRecurrenceIterator createIterator(Date now) {
   RRule rrule = createRRule();
   try {
     Log.d("RRULE", "Creating iterator for " + rrule.toIcal());
     if (now.before(startDate.getTime())) {
       now = startDate.getTime();
     }
     Calendar c = Calendar.getInstance();
     c.setTime(startDate.getTime());
     // c.set(Calendar.HOUR_OF_DAY, startDate.get(Calendar.HOUR_OF_DAY));
     // c.set(Calendar.MINUTE, startDate.get(Calendar.MINUTE));
     // c.set(Calendar.SECOND, startDate.get(Calendar.SECOND));
     c.set(Calendar.MILLISECOND, 0);
     return DateRecurrenceIterator.create(rrule, now, c.getTime());
   } catch (ParseException e) {
     Log.w("RRULE", "Unable to create iterator for " + rrule.toIcal());
     return DateRecurrenceIterator.empty();
   }
 }
  private static long handleWeeklyRepeatAfterComplete(
      RRule rrule, DateTime original, boolean hasDueTime) {
    List<WeekdayNum> byDay = rrule.getByDay();
    long newDate = original.getMillis();
    newDate += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
    DateTime date = new DateTime(newDate);

    Collections.sort(byDay, weekdayCompare);
    WeekdayNum next = findNextWeekday(byDay, date);

    do {
      date = date.plusDays(1);
    } while (date.getDayOfWeek() != next.wday.javaDayNum);

    long time = date.getMillis();
    if (hasDueTime) {
      return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
    } else {
      return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
    }
  }
Пример #10
0
    @Override
    public Void visitString(Property<String> property, UpgradeVisitorContainer<?> data) {
      String value = data.cursor.getString(data.columnIndex);

      if (property == Task.RECURRENCE) {
        LegacyRepeatInfo repeatInfo =
            LegacyRepeatInfo.fromSingleField(data.cursor.getInt(data.columnIndex));
        if (repeatInfo == null) data.model.setValue(property, "");
        else {
          RRule rrule = repeatInfo.toRRule();
          data.model.setValue(property, rrule.toIcal());
        }
      } else {
        data.model.setValue(property, value);
      }

      Log.d(
          "upgrade",
          "wrote " + value + " to -> " + property + " of model id " + data.cursor.getLong(1));
      return null;
    }
  @Test
  public void testDueDateSpecificTime() throws ParseException {
    buildRRule(1, Frequency.DAILY);

    // test specific day & time
    long dayWithTime =
        Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDate(2010, 8, 1, 10, 4, 0).getTime());
    task.setValue(Task.DUE_DATE, dayWithTime);

    long nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY;
    nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal(), false);
    assertDateTimeEquals(nextDayWithTime, nextDueDate);
  }
  private static long handleMonthlyRepeat(
      DateTime original, DateValue startDateAsDV, boolean hasDueTime, RRule rrule) {
    if (original.isLastDayOfMonth()) {
      int interval = rrule.getInterval();

      DateTime newDateTime = original.plusMonths(interval);
      long time = newDateTime.withDayOfMonth(newDateTime.getNumberOfDaysInMonth()).getMillis();
      if (hasDueTime) {
        return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
      } else {
        return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
      }
    } else {
      return invokeRecurrence(rrule, original, startDateAsDV);
    }
  }
  @Test
  public void testCompletionDateSpecificTime() throws ParseException {
    buildRRule(1, Frequency.DAILY);

    // test specific day & time
    long dayWithTime =
        Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDate(2010, 8, 1, 10, 4, 0).getTime());
    task.setValue(Task.DUE_DATE, dayWithTime);

    Date todayWithTime = newDate();
    todayWithTime.setHours(10);
    todayWithTime.setMinutes(4);
    todayWithTime.setSeconds(1);
    long nextDayWithTimeLong = todayWithTime.getTime();
    nextDayWithTimeLong += DateUtilities.ONE_DAY;
    nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000;

    nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal(), true);
    assertDateTimeEquals(nextDayWithTimeLong, nextDueDate);
  }
  /** Compute next due date */
  public static long computeNextDueDate(Task task, String recurrence) throws ParseException {
    boolean repeatAfterCompletion = task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION);
    RRule rrule = initRRule(recurrence);

    // initialize startDateAsDV
    Date original = setUpStartDate(task, repeatAfterCompletion, rrule.getFreq());
    DateValue startDateAsDV = setUpStartDateAsDV(task, original);

    if (rrule.getFreq() == Frequency.HOURLY || rrule.getFreq() == Frequency.MINUTELY)
      return handleSubdayRepeat(original, rrule);
    else if (rrule.getFreq() == Frequency.WEEKLY
        && rrule.getByDay().size() > 0
        && repeatAfterCompletion)
      return handleWeeklyRepeatAfterComplete(rrule, original, task.hasDueTime());
    else return invokeRecurrence(rrule, original, startDateAsDV);
  }
  /** Compute next due date */
  public static long computeNextDueDate(Task task, String recurrence, boolean repeatAfterCompletion)
      throws ParseException {
    RRule rrule = initRRule(recurrence);

    // initialize startDateAsDV
    DateTime original = setUpStartDate(task, repeatAfterCompletion, rrule.getFreq());
    DateValue startDateAsDV = setUpStartDateAsDV(task, original);

    if (rrule.getFreq() == Frequency.HOURLY || rrule.getFreq() == Frequency.MINUTELY) {
      return handleSubdayRepeat(original, rrule);
    } else if (rrule.getFreq() == Frequency.WEEKLY
        && rrule.getByDay().size() > 0
        && repeatAfterCompletion) {
      return handleWeeklyRepeatAfterComplete(rrule, original, task.hasDueTime());
    } else if (rrule.getFreq() == Frequency.MONTHLY) {
      return handleMonthlyRepeat(original, startDateAsDV, task.hasDueTime(), rrule);
    } else {
      return invokeRecurrence(rrule, original, startDateAsDV);
    }
  }
 private void buildRRule(int interval, Frequency freq, Weekday... weekdays) {
   rrule.setInterval(interval);
   rrule.setFreq(freq);
   setRRuleDays(rrule, weekdays);
 }
 private void setRRuleDays(RRule rrule, Weekday... weekdays) {
   ArrayList<WeekdayNum> days = new ArrayList<WeekdayNum>();
   for (Weekday wd : weekdays) days.add(new WeekdayNum(0, wd));
   rrule.setByDay(days);
 }
 private void computeNextDueDate(boolean fromComplete) throws ParseException {
   nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal(), fromComplete);
 }