fix for AST-167: allowing 'by day' type functionality for all repeats

pull/14/head
Tim Su 16 years ago
parent 9b6cbaf1b5
commit 1c0f60d9b6

@ -4,6 +4,7 @@ import java.text.DateFormatSymbols;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import android.app.Activity; import android.app.Activity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -65,6 +66,8 @@ public class RepeatControlSet implements TaskEditControlSet {
@Autowired @Autowired
ExceptionService exceptionService; ExceptionService exceptionService;
boolean setInterval = false;
// --- implementation // --- implementation
public RepeatControlSet(final Activity activity, ViewGroup parent) { public RepeatControlSet(final Activity activity, ViewGroup parent) {
@ -111,10 +114,22 @@ public class RepeatControlSet implements TaskEditControlSet {
repeatValueClick(); repeatValueClick();
} }
}); });
interval.setOnItemSelectedListener(new OnItemSelectedListener() { interval.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parentView, View view, int position, long id) { public void onItemSelected(AdapterView<?> parentView, View view, int position, long id) {
daysOfWeekContainer.setVisibility(position == INTERVAL_WEEKS ? View.VISIBLE : View.GONE); if(setInterval) {
setInterval = false;
return;
}
if(position == INTERVAL_WEEKS) {
int dayOfWeek = new Date().getDay();
for(int i = 0; i < 7; i++)
daysOfWeek[i].setChecked(i == dayOfWeek);
} else {
for(int i = 0; i < 7; i++)
daysOfWeek[i].setChecked(true);
}
} }
@Override @Override
@ -122,6 +137,7 @@ public class RepeatControlSet implements TaskEditControlSet {
// //
} }
}); });
daysOfWeekContainer.setVisibility(View.VISIBLE);
} }
/** Set up the repeat value button */ /** Set up the repeat value button */
@ -172,17 +188,6 @@ public class RepeatControlSet implements TaskEditControlSet {
break; break;
case WEEKLY: { case WEEKLY: {
interval.setSelection(INTERVAL_WEEKS); interval.setSelection(INTERVAL_WEEKS);
// clear all day of week checks, then update them
for(int i = 0; i < 7; i++)
daysOfWeek[i].setChecked(false);
for(WeekdayNum day : rrule.getByDay()) {
for(int i = 0; i < 7; i++)
if(daysOfWeek[i].getTag() == day.wday)
daysOfWeek[i].setChecked(true);
}
break; break;
} }
case MONTHLY: case MONTHLY:
@ -196,6 +201,19 @@ public class RepeatControlSet implements TaskEditControlSet {
exceptionService.reportError("repeat-unhandled-rule", //$NON-NLS-1$ exceptionService.reportError("repeat-unhandled-rule", //$NON-NLS-1$
new Exception("Unhandled rrule frequency: " + recurrence)); //$NON-NLS-1$ new Exception("Unhandled rrule frequency: " + recurrence)); //$NON-NLS-1$
} }
// clear all day of week checks, then update them
for(int i = 0; i < 7; i++)
daysOfWeek[i].setChecked(false);
for(WeekdayNum day : rrule.getByDay()) {
for(int i = 0; i < 7; i++)
if(daysOfWeek[i].getTag() == day.wday)
daysOfWeek[i].setChecked(true);
}
// suppress first call to interval.onItemSelected
setInterval = true;
} catch (ParseException e) { } catch (ParseException e) {
recurrence = ""; //$NON-NLS-1$ recurrence = ""; //$NON-NLS-1$
exceptionService.reportError("repeat-parse-exception", e); //$NON-NLS-1$ exceptionService.reportError("repeat-parse-exception", e); //$NON-NLS-1$
@ -226,11 +244,6 @@ public class RepeatControlSet implements TaskEditControlSet {
break; break;
case INTERVAL_WEEKS: { case INTERVAL_WEEKS: {
rrule.setFreq(Frequency.WEEKLY); rrule.setFreq(Frequency.WEEKLY);
ArrayList<WeekdayNum> days = new ArrayList<WeekdayNum>();
for(int i = 0; i < daysOfWeek.length; i++)
if(daysOfWeek[i].isChecked())
days.add(new WeekdayNum(0, (Weekday)daysOfWeek[i].getTag()));
rrule.setByDay(days);
break; break;
} }
case INTERVAL_MONTHS: case INTERVAL_MONTHS:
@ -239,6 +252,13 @@ public class RepeatControlSet implements TaskEditControlSet {
case INTERVAL_HOURS: case INTERVAL_HOURS:
rrule.setFreq(Frequency.HOURLY); rrule.setFreq(Frequency.HOURLY);
} }
ArrayList<WeekdayNum> days = new ArrayList<WeekdayNum>();
for(int i = 0; i < daysOfWeek.length; i++)
if(daysOfWeek[i].isChecked())
days.add(new WeekdayNum(0, (Weekday)daysOfWeek[i].getTag()));
rrule.setByDay(days);
result = rrule.toIcal(); result = rrule.toIcal();
} }
task.setValue(Task.RECURRENCE, result); task.setValue(Task.RECURRENCE, result);

@ -92,8 +92,8 @@ public class RepeatDetailExposer extends BroadcastReceiver implements DetailExpo
} }
interval = "<b>" + interval + "</b>"; //$NON-NLS-1$//$NON-NLS-2$ interval = "<b>" + interval + "</b>"; //$NON-NLS-1$//$NON-NLS-2$
if(rrule.getFreq() == Frequency.WEEKLY) { List<WeekdayNum> byDay = rrule.getByDay();
List<WeekdayNum> byDay = rrule.getByDay(); if(rrule.getFreq() == Frequency.WEEKLY || byDay.size() != 7) {
if(byDay.size() > 0) { if(byDay.size() > 0) {
StringBuilder byDayString = new StringBuilder(); StringBuilder byDayString = new StringBuilder();
DateFormatSymbols dfs = new DateFormatSymbols(); DateFormatSymbols dfs = new DateFormatSymbols();

@ -1,7 +1,9 @@
package com.todoroo.astrid.repeats; package com.todoroo.astrid.repeats;
import java.text.ParseException; import java.text.ParseException;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@ -15,6 +17,7 @@ import com.google.ical.values.DateValue;
import com.google.ical.values.DateValueImpl; import com.google.ical.values.DateValueImpl;
import com.google.ical.values.Frequency; import com.google.ical.values.Frequency;
import com.google.ical.values.RRule; import com.google.ical.values.RRule;
import com.google.ical.values.WeekdayNum;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService; import com.todoroo.andlib.service.ExceptionService;
@ -46,83 +49,116 @@ public class RepeatTaskCompleteListener extends BroadcastReceiver {
String recurrence = task.getValue(Task.RECURRENCE); String recurrence = task.getValue(Task.RECURRENCE);
if(recurrence != null && recurrence.length() > 0) { if(recurrence != null && recurrence.length() > 0) {
DateValue repeatFrom; long newDueDate;
Date repeatFromDate = new Date(); try {
newDueDate = computeNextDueDate(task, recurrence);
DateValue today = new DateValueImpl(repeatFromDate.getYear() + 1900, if(newDueDate == -1)
repeatFromDate.getMonth() + 1, repeatFromDate.getDate()); return;
if(task.hasDueDate() && !task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION)) { } catch (ParseException e) {
repeatFromDate = new Date(task.getValue(Task.DUE_DATE)); exceptionService.reportError("repeat-parse", e); //$NON-NLS-1$
if(task.hasDueTime()) { return;
repeatFrom = new DateTimeValueImpl(repeatFromDate.getYear() + 1900, }
repeatFromDate.getMonth() + 1, repeatFromDate.getDate(),
repeatFromDate.getHours(), repeatFromDate.getMinutes(), repeatFromDate.getSeconds()); long hideUntil = task.getValue(Task.HIDE_UNTIL);
} else { if(hideUntil > 0 && task.getValue(Task.DUE_DATE) > 0) {
repeatFrom = new DateValueImpl(repeatFromDate.getYear() + 1900, hideUntil += newDueDate - task.getValue(Task.DUE_DATE);
repeatFromDate.getMonth() + 1, repeatFromDate.getDate()); }
}
// clear recurrence from completed task so it can be re-commpleted
task.setValue(Task.RECURRENCE, ""); //$NON-NLS-1$
taskService.save(task, false);
// clone to create new task
task = taskService.clone(task);
task.setValue(Task.DUE_DATE, newDueDate);
task.setValue(Task.HIDE_UNTIL, hideUntil);
task.setValue(Task.COMPLETION_DATE, 0L);
task.setValue(Task.TIMER_START, 0L);
task.setValue(Task.ELAPSED_SECONDS, 0);
taskService.save(task, false);
}
}
public static long computeNextDueDate(Task task, String recurrence) throws ParseException {
DateValue repeatFrom;
Date repeatFromDate = new Date();
DateValue today = new DateValueImpl(repeatFromDate.getYear() + 1900,
repeatFromDate.getMonth() + 1, repeatFromDate.getDate());
if(task.hasDueDate() && !task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION)) {
repeatFromDate = new Date(task.getValue(Task.DUE_DATE));
if(task.hasDueTime()) {
repeatFrom = new DateTimeValueImpl(repeatFromDate.getYear() + 1900,
repeatFromDate.getMonth() + 1, repeatFromDate.getDate(),
repeatFromDate.getHours(), repeatFromDate.getMinutes(), repeatFromDate.getSeconds());
} else { } else {
repeatFrom = today; repeatFrom = new DateValueImpl(repeatFromDate.getYear() + 1900,
repeatFromDate.getMonth() + 1, repeatFromDate.getDate());
} }
} else {
repeatFrom = today;
}
// invoke the recurrence iterator // invoke the recurrence iterator
try { long newDueDate;
long newDueDate; RRule rrule = new RRule(recurrence);
RRule rrule = new RRule(recurrence);
if(rrule.getFreq() == Frequency.HOURLY) { // handle the iCalendar "byDay" field differently depending on if
newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, // we are weekly or otherwise
repeatFromDate.getTime() + DateUtilities.ONE_HOUR * rrule.getInterval());
} else { List<WeekdayNum> byDay = null;
RecurrenceIterator iterator = RecurrenceIteratorFactory.createRecurrenceIterator(rrule, if(rrule.getFreq() != Frequency.WEEKLY) {
repeatFrom, TimeZone.getDefault()); byDay = rrule.getByDay();
DateValue nextDate; rrule.setByDay(Collections.EMPTY_LIST);
if(repeatFrom.compareTo(today) < 0) { }
iterator.advanceTo(today);
if(!iterator.hasNext()) if(rrule.getFreq() == Frequency.HOURLY) {
return; newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME,
nextDate = iterator.next(); repeatFromDate.getTime() + DateUtilities.ONE_HOUR * rrule.getInterval());
} else { } else {
iterator.advanceTo(repeatFrom); RecurrenceIterator iterator = RecurrenceIteratorFactory.createRecurrenceIterator(rrule,
if(!iterator.hasNext()) repeatFrom, TimeZone.getDefault());
return; DateValue nextDate = repeatFrom;
nextDate = iterator.next(); if(repeatFrom.compareTo(today) < 0)
nextDate = iterator.next(); iterator.advanceTo(today);
}
for(int i = 0; i < 10; i++) { // ten tries then we give up
if(nextDate instanceof DateTimeValueImpl) { if(!iterator.hasNext())
DateTimeValueImpl newDateTime = (DateTimeValueImpl)nextDate; return -1;
newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, nextDate = iterator.next();
Date.UTC(newDateTime.year() - 1900, newDateTime.month() - 1, if(nextDate.compareTo(repeatFrom) != 0)
newDateTime.day(), newDateTime.hour(), break;
newDateTime.minute(), newDateTime.second())); }
} else { System.err.println("REPEAT started " + repeatFrom + ", ended " + nextDate); //$NON-NLS-1$ //$NON-NLS-2$
newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY,
new Date(nextDate.year() - 1900, nextDate.month() - 1, if(nextDate instanceof DateTimeValueImpl) {
nextDate.day()).getTime()); DateTimeValueImpl newDateTime = (DateTimeValueImpl)nextDate;
} newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME,
} Date.UTC(newDateTime.year() - 1900, newDateTime.month() - 1,
newDateTime.day(), newDateTime.hour(),
long hideUntil = task.getValue(Task.HIDE_UNTIL); newDateTime.minute(), newDateTime.second()));
if(hideUntil > 0 && task.getValue(Task.DUE_DATE) > 0) { } else {
hideUntil += newDueDate - task.getValue(Task.DUE_DATE); newDueDate = task.createDueDate(Task.URGENCY_SPECIFIC_DAY,
} new Date(nextDate.year() - 1900, nextDate.month() - 1,
nextDate.day()).getTime());
// clear recurrence from completed task so it can be re-commpleted
task.setValue(Task.RECURRENCE, ""); //$NON-NLS-1$
taskService.save(task, false);
// clone to create new task
task = taskService.clone(task);
task.setValue(Task.DUE_DATE, newDueDate);
task.setValue(Task.HIDE_UNTIL, hideUntil);
task.setValue(Task.COMPLETION_DATE, 0L);
task.setValue(Task.TIMER_START, 0L);
task.setValue(Task.ELAPSED_SECONDS, 0);
taskService.save(task, false);
} catch (ParseException e) {
exceptionService.reportError("recurrence-rule: " + recurrence, e); //$NON-NLS-1$
} }
} }
// what we do with the by day information is to add days until
// weekday equals one of this list
if(byDay != null && byDay.size() > 0) {
Date newDueDateDate = new Date(newDueDate);
outer: for(int i = 0; i < 7; i++) {
int weekday = newDueDateDate.getDay();
for(WeekdayNum wdn : byDay)
if(wdn.wday.jsDayNum == weekday)
break outer;
newDueDateDate.setDate(newDueDateDate.getDate() + 1);
}
newDueDate = newDueDateDate.getTime();
}
return newDueDate;
} }
} }

@ -15,12 +15,12 @@ import android.graphics.Paint;
import android.text.Html; import android.text.Html;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener; import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
@ -308,7 +308,10 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
// importance bar // importance bar
final View importanceView = viewHolder.importance; { final View importanceView = viewHolder.importance; {
int value = task.getValue(Task.IMPORTANCE); int value = task.getValue(Task.IMPORTANCE);
importanceView.setBackgroundColor(IMPORTANCE_COLORS[value]); if(value < IMPORTANCE_COLORS.length)
importanceView.setBackgroundColor(IMPORTANCE_COLORS[value]);
else
importanceView.setBackgroundColor(0);
} }
// details and decorations, expanded // details and decorations, expanded

@ -153,7 +153,7 @@ public class TaskDao extends GenericDao<Task> {
if(saveSuccessful) { if(saveSuccessful) {
task.markSaved(); task.markSaved();
afterSave(task, values, skipHooks); afterSave(task, values);
} }
return saveSuccessful; return saveSuccessful;
@ -208,9 +208,9 @@ public class TaskDao extends GenericDao<Task> {
* @param values values to be persisted to the database * @param values values to be persisted to the database
* @param skipHooks whether this save occurs as part of a sync * @param skipHooks whether this save occurs as part of a sync
*/ */
private void afterSave(Task task, ContentValues values, boolean skipHooks) { private void afterSave(Task task, ContentValues values) {
if(values.containsKey(Task.COMPLETION_DATE.name) && task.isCompleted()) if(values.containsKey(Task.COMPLETION_DATE.name) && task.isCompleted())
afterComplete(task, values, skipHooks); afterComplete(task, values);
else { else {
ReminderService.getInstance().scheduleAlarm(task); ReminderService.getInstance().scheduleAlarm(task);
} }
@ -218,9 +218,6 @@ public class TaskDao extends GenericDao<Task> {
Astrid2TaskProvider.notifyDatabaseModification(); Astrid2TaskProvider.notifyDatabaseModification();
ContextManager.getContext().startService(new Intent(ContextManager.getContext(), ContextManager.getContext().startService(new Intent(ContextManager.getContext(),
TasksWidget.UpdateService.class)); TasksWidget.UpdateService.class));
if(skipHooks)
return;
} }
/** /**
@ -230,14 +227,12 @@ public class TaskDao extends GenericDao<Task> {
* @param values * @param values
* @param duringSync * @param duringSync
*/ */
private void afterComplete(Task task, ContentValues values, boolean duringSync) { private void afterComplete(Task task, ContentValues values) {
// send broadcast // send broadcast
if(!duringSync) { Context context = ContextManager.getContext();
Context context = ContextManager.getContext(); Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_TASK_COMPLETED);
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_TASK_COMPLETED); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId());
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); context.sendOrderedBroadcast(broadcastIntent, null);
context.sendOrderedBroadcast(broadcastIntent, null);
}
} }
} }

@ -254,7 +254,7 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
} }
private void changeCurrent(int current, Animation in, Animation out) { private void changeCurrent(int current, Animation in, Animation out) {
current = notifyChange(); current = notifyChange(current);
// Wrap around the values if we go past the start or end // Wrap around the values if we go past the start or end
if (current > mEnd) { if (current > mEnd) {
@ -267,9 +267,9 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
updateView(); updateView();
} }
private int notifyChange() { private int notifyChange(int current) {
if (mListener != null) { if (mListener != null) {
return mListener.onChanged(this, mPrevious, mCurrent); return mListener.onChanged(this, mCurrent, current);
} else } else
return mCurrent; return mCurrent;
@ -294,7 +294,7 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
if ((val >= mStart) && (val <= mEnd)) { if ((val >= mStart) && (val <= mEnd)) {
mPrevious = mCurrent; mPrevious = mCurrent;
mCurrent = val; mCurrent = val;
notifyChange(); notifyChange(mCurrent);
} }
updateView(); updateView();
} }

@ -0,0 +1,113 @@
package com.todoroo.astrid.repeats;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum;
import com.todoroo.andlib.test.TodorooTestCase;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.model.Task;
public class AdvancedRepeatTests extends TodorooTestCase {
public static void assertDatesEqual(long date, long other) {
assertEquals("Expected: " + new Date(date) + ", Actual: " + new Date(other),
date, other);
}
public void testDailyWithDaysOfWeek() throws ParseException {
RRule rrule = new RRule();
rrule.setInterval(1);
rrule.setFreq(Frequency.DAILY);
rrule.setByDay(Collections.singletonList(new WeekdayNum(0, Weekday.FR)));
Task task = new Task();
long thursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 7, 1).getTime());
task.setValue(Task.DUE_DATE, thursday);
// repeat once => due date should become friday
long friday = thursday + DateUtilities.ONE_DAY;
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(friday, nextDueDate);
// repeat again => due date should be one week from friday
long nextFriday = friday + DateUtilities.ONE_WEEK;
task.setValue(Task.DUE_DATE, friday);
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(nextFriday, nextDueDate);
// now try with thursday, and repeat every 2 days. expect next friday
rrule.setInterval(2);
task.setValue(Task.DUE_DATE, thursday);
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(nextFriday, nextDueDate);
// again with friday, expect next friday
task.setValue(Task.DUE_DATE, friday);
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(nextFriday, nextDueDate);
}
public void testMonthlyWithDaysOfWeek() throws ParseException {
RRule rrule = new RRule();
rrule.setInterval(1);
rrule.setFreq(Frequency.MONTHLY);
rrule.setByDay(Arrays.asList(new WeekdayNum[] {
new WeekdayNum(0, Weekday.SU),
new WeekdayNum(0, Weekday.MO),
new WeekdayNum(0, Weekday.TU),
new WeekdayNum(0, Weekday.WE),
new WeekdayNum(0, Weekday.TH),
new WeekdayNum(0, Weekday.FR),
new WeekdayNum(0, Weekday.SA),
}));
Task task = new Task();
long thursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 7, 1).getTime());
task.setValue(Task.DUE_DATE, thursday);
// repeat once => due date should become next month on the first
long nextMonth = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 8, 1).getTime());
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(nextMonth, nextDueDate);
// only allow thursdays
rrule.setByDay(Arrays.asList(new WeekdayNum[] {
new WeekdayNum(0, Weekday.TH),
}));
long nextMonthOnThursday = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(113, 8, 5).getTime());
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(nextMonthOnThursday, nextDueDate);
}
public void testDueDateInPast() throws ParseException {
RRule rrule = new RRule();
rrule.setInterval(1);
rrule.setFreq(Frequency.DAILY);
Task task = new Task();
// repeat once => due date should become tomorrow
long past = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(110, 7, 1).getTime());
task.setValue(Task.DUE_DATE, past);
long today = task.createDueDate(Task.URGENCY_SPECIFIC_DAY, DateUtilities.now());
long nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(today, nextDueDate);
// test specific day & time
long pastWithTime = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, new Date(110, 7, 1, 10, 4).getTime());
task.setValue(Task.DUE_DATE, pastWithTime);
Date date = new Date(DateUtilities.now() / 1000L * 1000L);
date.setHours(10);
date.setMinutes(4);
long todayWithTime = task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, date.getTime());
nextDueDate = RepeatTaskCompleteListener.computeNextDueDate(task, rrule.toIcal());
assertDatesEqual(todayWithTime + DateUtilities.ONE_DAY, nextDueDate);
}
}
Loading…
Cancel
Save