From 50db04ffd69a2b5fcf51d267a5df18437babeeb5 Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Wed, 28 Mar 2012 14:58:56 -0700 Subject: [PATCH] Migrate handling of due times, take two --- api/src/com/todoroo/andlib/sql/Functions.java | 14 ++++ api/src/com/todoroo/astrid/data/Task.java | 24 ++---- .../astrid/helper/DueDateTimeMigrator.java | 80 +++++++++++++++++++ .../astrid/service/UpgradeService.java | 7 ++ .../com/todoroo/astrid/ui/CalendarView.java | 6 +- .../todoroo/astrid/ui/DateAndTimePicker.java | 6 +- 6 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 astrid/src/com/todoroo/astrid/helper/DueDateTimeMigrator.java diff --git a/api/src/com/todoroo/andlib/sql/Functions.java b/api/src/com/todoroo/andlib/sql/Functions.java index 9770fcfdc..a4cfc78ed 100644 --- a/api/src/com/todoroo/andlib/sql/Functions.java +++ b/api/src/com/todoroo/andlib/sql/Functions.java @@ -1,6 +1,7 @@ package com.todoroo.andlib.sql; import com.todoroo.andlib.data.Property.IntegerProperty; +import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.StringProperty; @@ -34,6 +35,18 @@ public final class Functions { return new Field("(strftime('%s','now')*1000 + " + millis + ")"); } + public static Field strftime(LongProperty field) { + return strftimeWithFormat(field, "%H:%M:%S"); + } + + public static Field strftimeWithFormat(LongProperty field, String format) { + return new Field("(strftime('" + format + "', datetime(" + field.toString() + "/1000, 'unixepoch', 'localtime')))"); + } + + public static Field strftimeSeconds(LongProperty field) { + return cast(strftimeWithFormat(field, "%S"), "LONG"); + } + public static Field cast(Field field, String newType) { return new Field("CAST(" + field.toString() + " AS " + newType + ")"); @@ -55,4 +68,5 @@ public final class Functions { return new Field(field.toString() + " & " + value); } + } diff --git a/api/src/com/todoroo/astrid/data/Task.java b/api/src/com/todoroo/astrid/data/Task.java index 777a3eafc..a677bd757 100644 --- a/api/src/com/todoroo/astrid/data/Task.java +++ b/api/src/com/todoroo/astrid/data/Task.java @@ -387,11 +387,11 @@ public final class Task extends RemoteModel { Date dueDate = new Date(date / 1000L * 1000L); // get rid of millis if(setting != URGENCY_SPECIFIC_DAY_TIME) { - dueDate.setHours(23); - dueDate.setMinutes(59); - dueDate.setSeconds(59); - } else if(isEndOfDay(dueDate)) { - dueDate.setSeconds(58); + dueDate.setHours(12); + dueDate.setMinutes(0); + dueDate.setSeconds(0); // Seconds == 0 means no due time + } else { + dueDate.setSeconds(1); // Seconds > 0 means due time exists } return dueDate.getTime(); } @@ -436,20 +436,12 @@ public final class Task extends RemoteModel { hideUntil.setHours(0); hideUntil.setMinutes(0); hideUntil.setSeconds(0); + } else { + hideUntil.setSeconds(1); } return hideUntil.getTime(); } - /** - * @return true if hours, minutes, and seconds indicate end of day - */ - private static boolean isEndOfDay(Date date) { - int hours = date.getHours(); - int minutes = date.getMinutes(); - int seconds = date.getSeconds(); - return hours == 23 && minutes == 59 && seconds == 59; - } - /** * Checks whether this due date has a due time or only a date */ @@ -463,7 +455,7 @@ public final class Task extends RemoteModel { * Checks whether provided due date has a due time or only a date */ public static boolean hasDueTime(long dueDate) { - return dueDate > 0 && !isEndOfDay(new Date(dueDate)); + return dueDate > 0 && (dueDate % 60000 > 0); } } diff --git a/astrid/src/com/todoroo/astrid/helper/DueDateTimeMigrator.java b/astrid/src/com/todoroo/astrid/helper/DueDateTimeMigrator.java new file mode 100644 index 000000000..e4173cffe --- /dev/null +++ b/astrid/src/com/todoroo/astrid/helper/DueDateTimeMigrator.java @@ -0,0 +1,80 @@ +package com.todoroo.astrid.helper; + +import java.util.Date; + +import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.Autowired; +import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.andlib.sql.Criterion; +import com.todoroo.andlib.sql.Functions; +import com.todoroo.andlib.sql.Query; +import com.todoroo.andlib.utility.Preferences; +import com.todoroo.astrid.dao.TaskDao; +import com.todoroo.astrid.data.Task; + +public class DueDateTimeMigrator { + + @Autowired TaskDao taskDao; + + private static final String PREF_MIGRATED_DUE_TIMES = "migrated_due_times"; //$NON-NLS-1$ + private static final String LEGACY_NO_TIME_STRING = "23:59:59"; //$NON-NLS-1$ + + public DueDateTimeMigrator() { + DependencyInjectionService.getInstance().inject(this); + } + + private interface TaskDateAdjuster { + public void adjust(Date date); + } + + public void migrateDueTimes() { + if (!Preferences.getBoolean(PREF_MIGRATED_DUE_TIMES, false)) { + // Get tasks with due time (i.e. due date != 23:59:59) + TodorooCursor tasksWithSeconds = taskDao.query(Query.select(Task.ID, Task.TITLE, Task.DUE_DATE).where( + Criterion.and(Task.DUE_DATE.gt(0), + Criterion.not(Functions.strftime(Task.DUE_DATE).eq(LEGACY_NO_TIME_STRING))))); + + // Set those tassk to have time HH:MM:00 + processCursor(tasksWithSeconds, new TaskDateAdjuster() { + @Override + public void adjust(Date date) { + date.setSeconds(1); + } + }); + + // Get tasks with no due time (i.e. due date = 23:59:59) + TodorooCursor tasksWithoutDueTime = taskDao.query(Query.select(Task.ID, Task.TITLE, Task.DUE_DATE).where( + Criterion.and(Task.DUE_DATE.gt(0), + Functions.strftime(Task.DUE_DATE).eq(LEGACY_NO_TIME_STRING)))); + + // Set those tasks to have time 12:00:00 + processCursor(tasksWithoutDueTime, new TaskDateAdjuster() { + @Override + public void adjust(Date date) { + date.setHours(12); + date.setMinutes(0); + date.setSeconds(0); + } + }); + Preferences.setBoolean(PREF_MIGRATED_DUE_TIMES, true); + } + } + + private void processCursor(TodorooCursor cursor, TaskDateAdjuster adjuster) { + Task curr = new Task(); + try { + for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { + curr.readFromCursor(cursor); + System.err.println("Processing task: " + curr.getValue(Task.TITLE) + ", ID: " + curr.getId()); + long time = curr.getValue(Task.DUE_DATE) / 1000L * 1000L; + Date date = new Date(time); + adjuster.adjust(date); + curr.setValue(Task.DUE_DATE, date.getTime()); + taskDao.save(curr); + } + } finally { + cursor.close(); + } + } + +} diff --git a/astrid/src/com/todoroo/astrid/service/UpgradeService.java b/astrid/src/com/todoroo/astrid/service/UpgradeService.java index 4c0423a04..3f1b091c5 100644 --- a/astrid/src/com/todoroo/astrid/service/UpgradeService.java +++ b/astrid/src/com/todoroo/astrid/service/UpgradeService.java @@ -31,6 +31,7 @@ import com.todoroo.astrid.dao.Database; import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksPreferenceService; +import com.todoroo.astrid.helper.DueDateTimeMigrator; import com.todoroo.astrid.notes.NoteMetadata; import com.todoroo.astrid.producteev.sync.ProducteevDataService; import com.todoroo.astrid.service.abtesting.ABChooser; @@ -40,6 +41,7 @@ import com.todoroo.astrid.utility.AstridPreferences; public final class UpgradeService { + public static final int V4_0_6 = 262; public static final int V4_0_5_1 = 261; public static final int V4_0_5 = 260; public static final int V4_0_4_3 = 259; @@ -143,6 +145,10 @@ public final class UpgradeService { Preferences.setInt(AstridPreferences.P_UPGRADE_FROM, from); + // This needs to happen synchronously otherwise the tasklist will look wrong on first launch. + if (from < V4_0_6) + new DueDateTimeMigrator().migrateDueTimes(); + new Thread(new Runnable() { @Override public void run() { @@ -158,6 +164,7 @@ public final class UpgradeService { if(from < V3_8_4 && Preferences.getBoolean(R.string.p_showNotes, false)) taskService.clearDetails(Task.NOTES.neq("")); //$NON-NLS-1$ + } finally { DialogUtilities.dismissDialog((Activity)context, dialog); } diff --git a/astrid/src/com/todoroo/astrid/ui/CalendarView.java b/astrid/src/com/todoroo/astrid/ui/CalendarView.java index 190e0f0c5..e4645d5b2 100644 --- a/astrid/src/com/todoroo/astrid/ui/CalendarView.java +++ b/astrid/src/com/todoroo/astrid/ui/CalendarView.java @@ -455,9 +455,9 @@ public class CalendarView extends View { private Date getToday(Calendar calendar) { Date today = calendar.getTime(); today.setTime(today.getTime() / 1000L * 1000L); - today.setHours(23); - today.setMinutes(59); - today.setSeconds(59); + today.setHours(12); + today.setMinutes(0); + today.setSeconds(0); return today; } diff --git a/astrid/src/com/todoroo/astrid/ui/DateAndTimePicker.java b/astrid/src/com/todoroo/astrid/ui/DateAndTimePicker.java index 26e3999dd..fb554fdb4 100644 --- a/astrid/src/com/todoroo/astrid/ui/DateAndTimePicker.java +++ b/astrid/src/com/todoroo/astrid/ui/DateAndTimePicker.java @@ -87,9 +87,9 @@ public class DateAndTimePicker extends LinearLayout { private Date getDateForCalendar(Date date) { Date forCalendar = new Date(date.getTime() / 1000L * 1000L); - forCalendar.setHours(23); - forCalendar.setMinutes(59); - forCalendar.setSeconds(59); + forCalendar.setHours(12); + forCalendar.setMinutes(0); + forCalendar.setSeconds(0); return forCalendar; }