Refactor reminders; replace int by WeekdayList

pull/151/head
Alinson S. Xavier 9 years ago
parent 37a9e793e7
commit 15a4a2c002

@ -263,7 +263,7 @@ public class MainTest
clickMenuItem(R.string.settings); clickMenuItem(R.string.settings);
String date = String date =
DateUtils.getBackupDateFormat().format(DateUtils.getLocalTime()); DateFormats.getBackupDateFormat().format(DateUtils.getLocalTime());
date = date.substring(0, date.length() - 2); date = date.substring(0, date.length() - 2);
clickSettingsItem("Export full backup"); clickSettingsItem("Export full backup");

@ -82,7 +82,8 @@ public class ImportTest extends BaseAndroidTest
Habit habit = habitList.getByPosition(0); Habit habit = habitList.getByPosition(0);
assertThat(habit.getName(), equalTo("Wake up early")); assertThat(habit.getName(), equalTo("Wake up early"));
assertThat(habit.getFrequency(), equalTo(Frequency.THREE_TIMES_PER_WEEK)); assertThat(habit.getFrequency(),
equalTo(Frequency.THREE_TIMES_PER_WEEK));
assertTrue(containsRepetition(habit, 2016, 3, 14)); assertTrue(containsRepetition(habit, 2016, 3, 14));
assertTrue(containsRepetition(habit, 2016, 3, 16)); assertTrue(containsRepetition(habit, 2016, 3, 16));
assertFalse(containsRepetition(habit, 2016, 3, 17)); assertFalse(containsRepetition(habit, 2016, 3, 17));
@ -115,8 +116,7 @@ public class ImportTest extends BaseAndroidTest
assertThat(reminder.getHour(), equalTo(8)); assertThat(reminder.getHour(), equalTo(8));
assertThat(reminder.getMinute(), equalTo(0)); assertThat(reminder.getMinute(), equalTo(0));
boolean[] reminderDays = { false, true, true, true, true, true, false }; boolean[] reminderDays = { false, true, true, true, true, true, false };
assertThat(reminder.getDays(), assertThat(reminder.getDays().toArray(), equalTo(reminderDays));
equalTo(DateUtils.packWeekdayList(reminderDays)));
} }
@Test @Test

@ -25,7 +25,6 @@ import android.view.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;
import org.junit.runner.*; import org.junit.runner.*;
@ -46,7 +45,7 @@ public class SubtitleCardTest extends BaseViewTest
super.setUp(); super.setUp();
habit = fixtures.createLongHabit(); habit = fixtures.createLongHabit();
habit.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
view = (SubtitleCard) LayoutInflater view = (SubtitleCard) LayoutInflater
.from(targetContext) .from(targetContext)

@ -45,7 +45,7 @@ public class HabitLogger
int min = Math.min(3, habit.getName().length()); int min = Math.min(3, habit.getName().length());
String name = habit.getName().substring(0, min); String name = habit.getName().substring(0, min);
DateFormat df = DateUtils.getBackupDateFormat(); DateFormat df = DateFormats.getBackupDateFormat();
String time = df.format(new Date(reminderTime)); String time = df.format(new Date(reminderTime));
Log.i("ReminderHelper", Log.i("ReminderHelper",

@ -151,7 +151,7 @@ public class HabitsCSVExporter
private String writeZipFile() throws IOException private String writeZipFile() throws IOException
{ {
SimpleDateFormat dateFormat = DateUtils.getCSVDateFormat(); SimpleDateFormat dateFormat = DateFormats.getCSVDateFormat();
String date = dateFormat.format(DateUtils.getStartOfToday()); String date = dateFormat.format(DateUtils.getStartOfToday());
String zipFilename = String zipFilename =
String.format("%s/Loop Habits CSV %s.zip", exportDirName, date); String.format("%s/Loop Habits CSV %s.zip", exportDirName, date);

@ -203,7 +203,7 @@ public class RewireDBImporter extends AbstractImporter
int hour = rewireReminder / 60; int hour = rewireReminder / 60;
int minute = rewireReminder % 60; int minute = rewireReminder % 60;
Integer days = DateUtils.packWeekdayList(reminderDays); WeekdayList days = new WeekdayList(reminderDays);
Reminder reminder = new Reminder(hour, minute, days); Reminder reminder = new Reminder(hour, minute, days);
habit.setReminder(reminder); habit.setReminder(reminder);

@ -161,7 +161,7 @@ public abstract class CheckmarkList
int values[] = getAllValues(); int values[] = getAllValues();
long timestamp = DateUtils.getStartOfToday(); long timestamp = DateUtils.getStartOfToday();
SimpleDateFormat dateFormat = DateUtils.getCSVDateFormat(); SimpleDateFormat dateFormat = DateFormats.getCSVDateFormat();
for (int value : values) for (int value : values)
{ {

@ -19,29 +19,25 @@
package org.isoron.uhabits.models; package org.isoron.uhabits.models;
import android.support.annotation.*;
public final class Reminder public final class Reminder
{ {
private final int hour; private final int hour;
private final int minute; private final int minute;
private final int days; private final WeekdayList days;
public Reminder(int hour, int minute, int days) public Reminder(int hour, int minute, @NonNull WeekdayList days)
{ {
this.hour = hour; this.hour = hour;
this.minute = minute; this.minute = minute;
this.days = days; this.days = days;
} }
/** @NonNull
* Returns the days of the week the reminder should be shown. public WeekdayList getDays()
* <p>
* This field can be converted to a list of booleans using the method
* DateUtils.unpackWeekdayList and converted back to an integer by using the
* method DateUtils.packWeekdayList.
*/
public int getDays()
{ {
return days; return days;
} }

@ -128,7 +128,7 @@ public abstract class ScoreList implements Iterable<Score>
public void writeCSV(Writer out) throws IOException public void writeCSV(Writer out) throws IOException
{ {
computeAll(); computeAll();
SimpleDateFormat dateFormat = DateUtils.getCSVDateFormat(); SimpleDateFormat dateFormat = DateFormats.getCSVDateFormat();
for (Score s : this) for (Score s : this)
{ {

@ -0,0 +1,65 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.models;
import java.util.*;
public class WeekdayList
{
public static WeekdayList EVERY_DAY = new WeekdayList(127);
private final boolean[] weekdays;
public WeekdayList(int packedList)
{
weekdays = new boolean[7];
int current = 1;
for (int i = 0; i < 7; i++)
{
if ((packedList & current) != 0) weekdays[i] = true;
current = current << 1;
}
}
public WeekdayList(boolean weekdays[])
{
this.weekdays = Arrays.copyOf(weekdays, 7);
}
public boolean[] toArray()
{
return weekdays;
}
public int toInteger()
{
int packedList = 0;
int current = 1;
for (int i = 0; i < 7; i++)
{
if (weekdays[i]) packedList |= current;
current = current << 1;
}
return packedList;
}
}

@ -154,7 +154,7 @@ public class HabitRecord extends Model implements SQLiteRecord
Reminder reminder = model.getReminder(); Reminder reminder = model.getReminder();
this.reminderHour = reminder.getHour(); this.reminderHour = reminder.getHour();
this.reminderMin = reminder.getMinute(); this.reminderMin = reminder.getMinute();
this.reminderDays = reminder.getDays(); this.reminderDays = reminder.getDays().toInteger();
} }
} }
@ -186,8 +186,8 @@ public class HabitRecord extends Model implements SQLiteRecord
if (reminderHour != null && reminderMin != null) if (reminderHour != null && reminderMin != null)
{ {
habit.setReminder( habit.setReminder(new Reminder(reminderHour, reminderMin,
new Reminder(reminderHour, reminderMin, reminderDays)); new WeekdayList(reminderDays)));
} }
} }

@ -241,8 +241,7 @@ public class ReminderReceiver extends BroadcastReceiver
Long timestamp = Long timestamp =
intent.getLongExtra("timestamp", DateUtils.getStartOfToday()); intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
boolean reminderDays[] = boolean reminderDays[] = reminder.getDays().toArray();
DateUtils.unpackWeekdayList(reminder.getDays());
int weekday = DateUtils.getWeekday(timestamp); int weekday = DateUtils.getWeekday(timestamp);
return reminderDays[weekday]; return reminderDays[weekday];

@ -26,7 +26,6 @@ import android.view.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;
@ -72,7 +71,7 @@ public class BaseSystem
@NonNull @NonNull
public File dumpBugReportToFile() throws IOException public File dumpBugReportToFile() throws IOException
{ {
String date = DateUtils.getBackupDateFormat().format( String date = DateFormats.getBackupDateFormat().format(
DateUtils.getLocalTime()); DateUtils.getLocalTime());
if (context == null) throw new RuntimeException( if (context == null) throw new RuntimeException(

@ -281,8 +281,8 @@ public class FrequencyChart extends ScrollableChart
private void initDateFormats() private void initDateFormats()
{ {
dfMonth = DateUtils.getDateFormat("MMM"); dfMonth = DateFormats.fromSkeleton("MMM");
dfYear = DateUtils.getDateFormat("yyyy"); dfYear = DateFormats.fromSkeleton("yyyy");
} }
private void initRects() private void initRects()

@ -385,8 +385,8 @@ public class HistoryChart extends ScrollableChart
private void initDateFormats() private void initDateFormats()
{ {
dfMonth = DateUtils.getDateFormat("MMM"); dfMonth = DateFormats.fromSkeleton("MMM");
dfYear = DateUtils.getDateFormat("yyyy"); dfYear = DateFormats.fromSkeleton("yyyy");
} }
private void initRects() private void initRects()

@ -412,9 +412,9 @@ public class ScoreChart extends ScrollableChart
private void initDateFormats() private void initDateFormats()
{ {
dfYear = DateUtils.getDateFormat("yyyy"); dfYear = DateFormats.fromSkeleton("yyyy");
dfMonth = DateUtils.getDateFormat("MMM"); dfMonth = DateFormats.fromSkeleton("MMM");
dfDay = DateUtils.getDateFormat("d"); dfDay = DateFormats.fromSkeleton("d");
} }
private void initPaints() private void initPaints()

@ -31,7 +31,6 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.common.dialogs.*; import org.isoron.uhabits.ui.common.dialogs.*;
import org.isoron.uhabits.utils.DateUtils;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
@ -102,7 +101,7 @@ public abstract class BaseDialog extends AppCompatDialogFragment
Reminder reminder = modifiedHabit.getReminder(); Reminder reminder = modifiedHabit.getReminder();
outState.putInt("reminderMin", reminder.getMinute()); outState.putInt("reminderMin", reminder.getMinute());
outState.putInt("reminderHour", reminder.getHour()); outState.putInt("reminderHour", reminder.getHour());
outState.putInt("reminderDays", reminder.getDays()); outState.putInt("reminderDays", reminder.getDays().toInteger());
} }
} }
@ -125,7 +124,8 @@ public abstract class BaseDialog extends AppCompatDialogFragment
if (hour >= 0 && minute >= 0) if (hour >= 0 && minute >= 0)
{ {
Reminder reminder = new Reminder(hour, minute, days); Reminder reminder =
new Reminder(hour, minute, new WeekdayList(days));
modifiedHabit.setReminder(reminder); modifiedHabit.setReminder(reminder);
} }
} }
@ -173,7 +173,7 @@ public abstract class BaseDialog extends AppCompatDialogFragment
WeekdayPickerDialog dialog = new WeekdayPickerDialog(); WeekdayPickerDialog dialog = new WeekdayPickerDialog();
dialog.setListener(new OnWeekdaysPickedListener()); dialog.setListener(new OnWeekdaysPickedListener());
dialog.setSelectedDays(DateUtils.unpackWeekdayList(reminder.getDays())); dialog.setSelectedDays(reminder.getDays().toArray());
dialog.show(getFragmentManager(), "weekdayPicker"); dialog.show(getFragmentManager(), "weekdayPicker");
} }
@ -215,7 +215,7 @@ public abstract class BaseDialog extends AppCompatDialogFragment
public void onTimeSet(RadialPickerLayout view, int hour, int minute) public void onTimeSet(RadialPickerLayout view, int hour, int minute)
{ {
Reminder reminder = Reminder reminder =
new Reminder(hour, minute, DateUtils.ALL_WEEK_DAYS); new Reminder(hour, minute, WeekdayList.EVERY_DAY);
modifiedHabit.setReminder(reminder); modifiedHabit.setReminder(reminder);
helper.populateReminderFields(modifiedHabit); helper.populateReminderFields(modifiedHabit);
} }
@ -232,7 +232,7 @@ public abstract class BaseDialog extends AppCompatDialogFragment
Reminder oldReminder = modifiedHabit.getReminder(); Reminder oldReminder = modifiedHabit.getReminder();
modifiedHabit.setReminder( modifiedHabit.setReminder(
new Reminder(oldReminder.getHour(), oldReminder.getMinute(), new Reminder(oldReminder.getHour(), oldReminder.getMinute(),
DateUtils.packWeekdayList(selectedDays))); new WeekdayList(selectedDays)));
helper.populateReminderFields(modifiedHabit); helper.populateReminderFields(modifiedHabit);
} }

@ -144,7 +144,7 @@ public class BaseDialogHelper
tvReminderTime.setText(time); tvReminderTime.setText(time);
llReminderDays.setVisibility(View.VISIBLE); llReminderDays.setVisibility(View.VISIBLE);
boolean weekdays[] = DateUtils.unpackWeekdayList(reminder.getDays()); boolean weekdays[] = reminder.getDays().toArray();
tvReminderDays.setText( tvReminderDays.setText(
DateUtils.formatWeekdayList(frag.getContext(), weekdays)); DateUtils.formatWeekdayList(frag.getContext(), weekdays));
} }

@ -109,7 +109,7 @@ public abstract class DatabaseUtils
{ {
File db = getDatabaseFile(); File db = getDatabaseFile();
SimpleDateFormat dateFormat = DateUtils.getBackupDateFormat(); SimpleDateFormat dateFormat = DateFormats.getBackupDateFormat();
String date = dateFormat.format(DateUtils.getLocalTime()); String date = dateFormat.format(DateUtils.getLocalTime());
File dbCopy = new File( File dbCopy = new File(
String.format("%s/Loop Habits Backup %s.db", dir.getAbsolutePath(), String.format("%s/Loop Habits Backup %s.db", dir.getAbsolutePath(),

@ -0,0 +1,62 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.utils;
import android.support.annotation.*;
import java.text.*;
import java.util.*;
import static android.os.Build.VERSION.*;
import static android.os.Build.VERSION_CODES.*;
import static android.text.format.DateFormat.*;
public class DateFormats
{
@NonNull
private static SimpleDateFormat fromSkeleton(@NonNull String skeleton,
@NonNull Locale locale)
{
SimpleDateFormat df = new SimpleDateFormat(skeleton, locale);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
return df;
}
@NonNull
public static SimpleDateFormat fromSkeleton(@NonNull String skeleton)
{
Locale locale = Locale.getDefault();
if (SDK_INT >= JELLY_BEAN)
skeleton = getBestDateTimePattern(locale, skeleton);
return fromSkeleton(skeleton, locale);
}
public static SimpleDateFormat getBackupDateFormat()
{
return fromSkeleton("yyyy-MM-dd HHmmss", Locale.US);
}
public static SimpleDateFormat getCSVDateFormat()
{
return fromSkeleton("yyyy-MM-dd", Locale.US);
}
}

@ -19,21 +19,17 @@
package org.isoron.uhabits.utils; package org.isoron.uhabits.utils;
import android.content.Context; import android.content.*;
import android.text.format.DateFormat; import android.text.format.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.*;
import java.text.SimpleDateFormat; import java.util.*;
import java.util.Calendar;
import java.util.Date; import static java.util.Calendar.*;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
public abstract class DateUtils public abstract class DateUtils
{ {
public static int ALL_WEEK_DAYS = 127;
private static Long fixedLocalTime = null; private static Long fixedLocalTime = null;
@ -44,11 +40,9 @@ public abstract class DateUtils
public static String formatHeaderDate(GregorianCalendar day) public static String formatHeaderDate(GregorianCalendar day)
{ {
String dayOfMonth = Locale locale = Locale.getDefault();
Integer.toString(day.get(GregorianCalendar.DAY_OF_MONTH)); String dayOfMonth = Integer.toString(day.get(DAY_OF_MONTH));
String dayOfWeek = day.getDisplayName(GregorianCalendar.DAY_OF_WEEK, String dayOfWeek = day.getDisplayName(DAY_OF_WEEK, SHORT, locale);
GregorianCalendar.SHORT, Locale.getDefault());
return dayOfWeek + "\n" + dayOfMonth; return dayOfWeek + "\n" + dayOfMonth;
} }
@ -94,24 +88,6 @@ public abstract class DateUtils
return buffer.toString(); return buffer.toString();
} }
public static SimpleDateFormat getBackupDateFormat()
{
SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd HHmmss", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat;
}
public static SimpleDateFormat getCSVDateFormat()
{
SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat;
}
public static GregorianCalendar getCalendar(long timestamp) public static GregorianCalendar getCalendar(long timestamp)
{ {
GregorianCalendar day = GregorianCalendar day =
@ -120,34 +96,18 @@ public abstract class DateUtils
return day; return day;
} }
public static SimpleDateFormat getDateFormat(String skeleton)
{
String pattern;
Locale locale = Locale.getDefault();
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
pattern = DateFormat.getBestDateTimePattern(locale, skeleton);
else pattern = skeleton;
SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
return format;
}
public static String[] getDayNames(int format) public static String[] getDayNames(int format)
{ {
String[] wdays = new String[7]; String[] wdays = new String[7];
Calendar day = new GregorianCalendar(); Calendar day = new GregorianCalendar();
day.set(GregorianCalendar.DAY_OF_WEEK, Calendar.SATURDAY); day.set(DAY_OF_WEEK, Calendar.SATURDAY);
for (int i = 0; i < wdays.length; i++) for (int i = 0; i < wdays.length; i++)
{ {
wdays[i] = day.getDisplayName(GregorianCalendar.DAY_OF_WEEK, format, wdays[i] =
Locale.getDefault()); day.getDisplayName(DAY_OF_WEEK, format, Locale.getDefault());
day.add(GregorianCalendar.DAY_OF_MONTH, 1); day.add(DAY_OF_MONTH, 1);
} }
return wdays; return wdays;
@ -171,14 +131,12 @@ public abstract class DateUtils
String[] days = new String[7]; String[] days = new String[7];
Calendar calendar = new GregorianCalendar(); Calendar calendar = new GregorianCalendar();
calendar.set(GregorianCalendar.DAY_OF_WEEK, calendar.set(DAY_OF_WEEK, calendar.getFirstDayOfWeek());
calendar.getFirstDayOfWeek());
for (int i = 0; i < days.length; i++) for (int i = 0; i < days.length; i++)
{ {
days[i] = days[i] = calendar.getDisplayName(DAY_OF_WEEK, format,
calendar.getDisplayName(GregorianCalendar.DAY_OF_WEEK, format, Locale.getDefault());
Locale.getDefault()); calendar.add(DAY_OF_MONTH, 1);
calendar.add(GregorianCalendar.DAY_OF_MONTH, 1);
} }
return days; return days;
@ -192,12 +150,11 @@ public abstract class DateUtils
{ {
Integer[] dayNumbers = new Integer[7]; Integer[] dayNumbers = new Integer[7];
Calendar calendar = new GregorianCalendar(); Calendar calendar = new GregorianCalendar();
calendar.set(GregorianCalendar.DAY_OF_WEEK, calendar.set(DAY_OF_WEEK, calendar.getFirstDayOfWeek());
calendar.getFirstDayOfWeek());
for (int i = 0; i < dayNumbers.length; i++) for (int i = 0; i < dayNumbers.length; i++)
{ {
dayNumbers[i] = calendar.get(GregorianCalendar.DAY_OF_WEEK); dayNumbers[i] = calendar.get(DAY_OF_WEEK);
calendar.add(GregorianCalendar.DAY_OF_MONTH, 1); calendar.add(DAY_OF_MONTH, 1);
} }
return dayNumbers; return dayNumbers;
} }
@ -209,7 +166,7 @@ public abstract class DateUtils
public static String[] getShortDayNames() public static String[] getShortDayNames()
{ {
return getDayNames(GregorianCalendar.SHORT); return getDayNames(SHORT);
} }
public static long getStartOfDay(long timestamp) public static long getStartOfDay(long timestamp)
@ -230,7 +187,7 @@ public abstract class DateUtils
public static int getWeekday(long timestamp) public static int getWeekday(long timestamp)
{ {
GregorianCalendar day = getCalendar(timestamp); GregorianCalendar day = getCalendar(timestamp);
return day.get(GregorianCalendar.DAY_OF_WEEK) % 7; return day.get(DAY_OF_WEEK) % 7;
} }
/** /**
@ -246,20 +203,6 @@ public abstract class DateUtils
return number % 7; return number % 7;
} }
public static Integer packWeekdayList(boolean weekday[])
{
int list = 0;
int current = 1;
for (int i = 0; i < 7; i++)
{
if (weekday[i]) list |= current;
current = current << 1;
}
return list;
}
public static void setFixedLocalTime(Long timestamp) public static void setFixedLocalTime(Long timestamp)
{ {
fixedLocalTime = timestamp; fixedLocalTime = timestamp;
@ -279,12 +222,12 @@ public abstract class DateUtils
switch (field) switch (field)
{ {
case MONTH: case MONTH:
cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(DAY_OF_MONTH, 1);
return cal.getTimeInMillis(); return cal.getTimeInMillis();
case WEEK_NUMBER: case WEEK_NUMBER:
int firstWeekday = cal.getFirstDayOfWeek(); int firstWeekday = cal.getFirstDayOfWeek();
int weekday = cal.get(Calendar.DAY_OF_WEEK); int weekday = cal.get(DAY_OF_WEEK);
int delta = weekday - firstWeekday; int delta = weekday - firstWeekday;
if (delta < 0) delta += 7; if (delta < 0) delta += 7;
cal.add(Calendar.DAY_OF_YEAR, -delta); cal.add(Calendar.DAY_OF_YEAR, -delta);
@ -292,13 +235,13 @@ public abstract class DateUtils
case QUARTER: case QUARTER:
int quarter = cal.get(Calendar.MONTH) / 3; int quarter = cal.get(Calendar.MONTH) / 3;
cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, quarter * 3); cal.set(Calendar.MONTH, quarter * 3);
return cal.getTimeInMillis(); return cal.getTimeInMillis();
case YEAR: case YEAR:
cal.set(Calendar.MONTH, Calendar.JANUARY); cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(DAY_OF_MONTH, 1);
return cal.getTimeInMillis(); return cal.getTimeInMillis();
default: default:
@ -306,20 +249,6 @@ public abstract class DateUtils
} }
} }
public static boolean[] unpackWeekdayList(int list)
{
boolean[] weekday = new boolean[7];
int current = 1;
for (int i = 0; i < 7; i++)
{
if ((list & current) != 0) weekday[i] = true;
current = current << 1;
}
return weekday;
}
public enum TruncateField public enum TruncateField
{ {
MONTH, WEEK_NUMBER, YEAR, QUARTER MONTH, WEEK_NUMBER, YEAR, QUARTER

@ -21,7 +21,6 @@ package org.isoron.uhabits.models;
import org.hamcrest.*; import org.hamcrest.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;
import java.io.*; import java.io.*;
@ -59,7 +58,7 @@ public class HabitListTest extends BaseUnitTest
allHabits.add(habit); allHabits.add(habit);
if (i % 3 == 0) if (i % 3 == 0)
habit.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
} }
habitsArray.get(0).setArchived(true); habitsArray.get(0).setArchived(true);

@ -19,8 +19,7 @@
package org.isoron.uhabits.models; package org.isoron.uhabits.models;
import org.isoron.uhabits.BaseUnitTest; import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.DateUtils;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@ -53,7 +52,7 @@ public class HabitTest extends BaseUnitTest
model.setArchived(true); model.setArchived(true);
model.setColor(0); model.setColor(0);
model.setFrequency(new Frequency(10, 20)); model.setFrequency(new Frequency(10, 20));
model.setReminder(new Reminder(8, 30, 1)); model.setReminder(new Reminder(8, 30, new WeekdayList(1)));
Habit habit = new Habit(); Habit habit = new Habit();
habit.copyFrom(model); habit.copyFrom(model);
@ -93,7 +92,7 @@ public class HabitTest extends BaseUnitTest
Habit h = new Habit(); Habit h = new Habit();
assertThat(h.hasReminder(), is(false)); assertThat(h.hasReminder(), is(false));
h.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); h.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
assertThat(h.hasReminder(), is(true)); assertThat(h.hasReminder(), is(true));
h.clearReminder(); h.clearReminder();

@ -20,7 +20,7 @@
package org.isoron.uhabits.models; package org.isoron.uhabits.models;
import org.isoron.uhabits.BaseUnitTest; import org.isoron.uhabits.BaseUnitTest;
import org.isoron.uhabits.utils.DateUtils; import org.isoron.uhabits.utils.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -177,7 +177,7 @@ public class ScoreListTest extends BaseUnitTest
private void log(List<Score> list) private void log(List<Score> list)
{ {
SimpleDateFormat df = DateUtils.getCSVDateFormat(); SimpleDateFormat df = DateFormats.getCSVDateFormat();
for (Score s : list) for (Score s : list)
log("%s %d", df.format(new Date(s.getTimestamp())), s.getValue()); log("%s %d", df.format(new Date(s.getTimestamp())), s.getValue());
} }

@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.models;
import org.isoron.uhabits.*;
import org.junit.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsEqual.*;
public class WeekdayListTest extends BaseUnitTest
{
@Test
public void test()
{
int daysInt = 124;
boolean[] daysArray = new boolean[]{
false, false, true, true, true, true, true
};
WeekdayList list = new WeekdayList(daysArray);
assertThat(list.toArray(), equalTo(daysArray));
assertThat(list.toInteger(), equalTo(daysInt));
list = new WeekdayList(daysInt);
assertThat(list.toArray(), equalTo(daysArray));
assertThat(list.toInteger(), equalTo(daysInt));
}
}

@ -19,21 +19,27 @@
package org.isoron.uhabits.utils; package org.isoron.uhabits.utils;
import org.isoron.uhabits.BaseUnitTest; import org.isoron.uhabits.*;
import org.junit.Test; import org.junit.*;
import java.text.DateFormat; import java.text.*;
import java.text.SimpleDateFormat; import java.util.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import static java.util.Calendar.*;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.MatcherAssert.*;
public class DateUtilsTest extends BaseUnitTest public class DateUtilsTest extends BaseUnitTest
{ {
@Test
public void testFormatHeaderDate()
{
long timestamp = timestamp(2015, DECEMBER, 31);
GregorianCalendar date = DateUtils.getCalendar(timestamp);
String formatted = DateUtils.formatHeaderDate(date);
assertThat(formatted, equalTo("Thu\n31"));
}
@Test @Test
public void testTruncate_dayOfWeek() public void testTruncate_dayOfWeek()
{ {
@ -72,10 +78,10 @@ public class DateUtilsTest extends BaseUnitTest
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected)); assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2016, Calendar.DECEMBER, 1); expected = timestamp(2016, DECEMBER, 1);
t0 = timestamp(2016, Calendar.DECEMBER, 1); t0 = timestamp(2016, DECEMBER, 1);
t1 = timestamp(2016, Calendar.DECEMBER, 15); t1 = timestamp(2016, DECEMBER, 15);
t2 = timestamp(2016, Calendar.DECEMBER, 31); t2 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected)); assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
@ -87,19 +93,19 @@ public class DateUtilsTest extends BaseUnitTest
{ {
DateUtils.TruncateField field = DateUtils.TruncateField.QUARTER; DateUtils.TruncateField field = DateUtils.TruncateField.QUARTER;
long expected = timestamp(2016, Calendar.JANUARY, 1); long expected = timestamp(2016, JANUARY, 1);
long t0 = timestamp(2016, Calendar.JANUARY, 20); long t0 = timestamp(2016, JANUARY, 20);
long t1 = timestamp(2016, Calendar.FEBRUARY, 15); long t1 = timestamp(2016, FEBRUARY, 15);
long t2 = timestamp(2016, Calendar.MARCH, 30); long t2 = timestamp(2016, MARCH, 30);
assertThat(DateUtils.truncate(field, t0), equalTo(expected)); assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected)); assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2016, Calendar.APRIL, 1); expected = timestamp(2016, APRIL, 1);
t0 = timestamp(2016, Calendar.APRIL, 1); t0 = timestamp(2016, APRIL, 1);
t1 = timestamp(2016, Calendar.MAY, 30); t1 = timestamp(2016, MAY, 30);
t2 = timestamp(2016, Calendar.JUNE, 20); t2 = timestamp(2016, JUNE, 20);
assertThat(DateUtils.truncate(field, t0), equalTo(expected)); assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
@ -111,36 +117,36 @@ public class DateUtilsTest extends BaseUnitTest
{ {
DateUtils.TruncateField field = DateUtils.TruncateField.YEAR; DateUtils.TruncateField field = DateUtils.TruncateField.YEAR;
long expected = timestamp(2016, Calendar.JANUARY, 1); long expected = timestamp(2016, JANUARY, 1);
long t0 = timestamp(2016, Calendar.JANUARY, 1); long t0 = timestamp(2016, JANUARY, 1);
long t1 = timestamp(2016, Calendar.FEBRUARY, 25); long t1 = timestamp(2016, FEBRUARY, 25);
long t2 = timestamp(2016, Calendar.DECEMBER, 31); long t2 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected)); assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected)); assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2017, Calendar.JANUARY, 1); expected = timestamp(2017, JANUARY, 1);
t0 = timestamp(2017, Calendar.JANUARY, 1); t0 = timestamp(2017, JANUARY, 1);
t1 = timestamp(2017, Calendar.MAY, 30); t1 = timestamp(2017, MAY, 30);
t2 = timestamp(2017, Calendar.DECEMBER, 31); t2 = timestamp(2017, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected)); assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected)); assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected)); assertThat(DateUtils.truncate(field, t2), equalTo(expected));
} }
private void log(long timestamp)
{
DateFormat df = SimpleDateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
log("%s", df.format(new Date(timestamp)));
}
public long timestamp(int year, int month, int day) public long timestamp(int year, int month, int day)
{ {
GregorianCalendar cal = DateUtils.getStartOfTodayCalendar(); GregorianCalendar cal = DateUtils.getStartOfTodayCalendar();
cal.set(year, month, day); cal.set(year, month, day);
return cal.getTimeInMillis(); return cal.getTimeInMillis();
} }
private void log(long timestamp)
{
DateFormat df = SimpleDateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
log("%s", df.format(new Date(timestamp)));
}
} }

@ -52,7 +52,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
long atTime = 1422617400000L; // 11:30 jan 30, 2015 (UTC) long atTime = 1422617400000L; // 11:30 jan 30, 2015 (UTC)
long expectedCheckmarkTime = 1422576000000L; // 00:00 jan 27, 2015 (UTC) long expectedCheckmarkTime = 1422576000000L; // 00:00 jan 27, 2015 (UTC)
habit.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
scheduleAndVerify(atTime, expectedCheckmarkTime, atTime); scheduleAndVerify(atTime, expectedCheckmarkTime, atTime);
} }
@ -65,7 +65,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
long expectedCheckmarkTime = 1422230400000L; // 00:00 jan 26, 2015 (UTC) long expectedCheckmarkTime = 1422230400000L; // 00:00 jan 26, 2015 (UTC)
long expectedReminderTime = 1422261000000L; // 08:30 jan 26, 2015 (UTC) long expectedReminderTime = 1422261000000L; // 08:30 jan 26, 2015 (UTC)
habit.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime); scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime);
} }
@ -79,10 +79,10 @@ public class ReminderSchedulerTest extends BaseUnitTest
fixtures.purgeHabits(); fixtures.purgeHabits();
Habit h1 = fixtures.createEmptyHabit(); Habit h1 = fixtures.createEmptyHabit();
h1.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); h1.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
Habit h2 = fixtures.createEmptyHabit(); Habit h2 = fixtures.createEmptyHabit();
h2.setReminder(new Reminder(18, 30, DateUtils.ALL_WEEK_DAYS)); h2.setReminder(new Reminder(18, 30, WeekdayList.EVERY_DAY));
fixtures.createEmptyHabit(); fixtures.createEmptyHabit();
@ -102,7 +102,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
long expectedCheckmarkTime = 1453852800000L; // 00:00 jan 27, 2016 (UTC) long expectedCheckmarkTime = 1453852800000L; // 00:00 jan 27, 2016 (UTC)
long expectedReminderTime = 1453883400000L; // 08:30 jan 27, 2016 (UTC) long expectedReminderTime = 1453883400000L; // 08:30 jan 27, 2016 (UTC)
habit.setReminder(new Reminder(8, 30, DateUtils.ALL_WEEK_DAYS)); habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime); scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime);
} }

Loading…
Cancel
Save