package info.opencards.learnstrats.ltm; import info.opencards.Utils; import info.opencards.core.Item; import info.opencards.ui.preferences.GlobLearnSettings; import junit.framework.Assert; import org.junit.Test; import java.text.DateFormat; import java.text.ParseException; import java.util.*; import static java.util.Calendar.*; /** * Some utility-methods which ease date-computations. * * @author Holger Brandl */ public class ScheduleUtils { /** * Used for testing-purposes of the scheduling algorithm, where it is sometimes necessary to hack the value of * 'today'. */ public static Date testToday; public static Date getToday() { if (testToday != null) return testToday; return new Date(System.currentTimeMillis()); } public static boolean isToday(Date date) { Calendar today = new GregorianCalendar(); today.setTime(getToday()); Calendar cDate = new GregorianCalendar(); cDate.setTime(date); return today.get(YEAR) == cDate.get(YEAR) && today.get(MONTH) == cDate.get(MONTH) && today.get(DAY_OF_MONTH) == cDate.get(DAY_OF_MONTH); } public static boolean isBeforeToday(Date date) { return date.compareTo(getToday()) < 0; } public static Date getIncDate(Date lastQueryDate, int numDays) { Calendar cal = getInstance(); cal.setTime(lastQueryDate); // Set it in the Calendar object cal.add(DATE, numDays); // add the day-increment according to the given learning scheme return cal.getTime(); } private static final String LEARN_DATE = "numLearntDate"; private static final String NUM_LEARNT_TODAY = "numLearntToday"; public static int getNumLearntToday() { String lastLearnData = Utils.getPrefs().get(LEARN_DATE, DateFormat.getInstance().format(getToday())); try { Date lastLearnDate = DateFormat.getInstance().parse(lastLearnData); if (isToday(lastLearnDate)) { return Utils.getPrefs().getInt(NUM_LEARNT_TODAY, 0); } else { return 0; } } catch (ParseException e) { e.printStackTrace(); } return 0; } public static void setNumLearntToday(int numLearntToday) { Utils.getPrefs().put(LEARN_DATE, DateFormat.getInstance().format(getToday())); Utils.getPrefs().putInt(NUM_LEARNT_TODAY, numLearntToday); } public static int getMaxCardToBeLearntToday() { return Math.max(0, getMaxNewCardsPerDay() - getNumLearntToday()); } public static int getMaxNewCardsPerDay() { return Utils.getPrefs().getInt(GlobLearnSettings.NUM_ITEMS_PER_DAY, GlobLearnSettings.NUM_ITEMS_PER_DAY_DEFAULT); } /** * Reduce the number of new items to the given amount of <code>maxNumNew</code> and keep all no-new items. */ public static ArrayList<Item> getNewReducedItCo(ArrayList<Item> items, int maxNumNew) { ArrayList<Item> redItCo = new LTMCollection(); int numNewItemsIncluded = 0; for (Item item : items) { if (((LTMItem) item).isNew()) { if (numNewItemsIncluded < maxNumNew) { redItCo.add(item); numNewItemsIncluded++; } } else redItCo.add(item); } return redItCo; } /** * Extract all new items from a list and ignore already known items. */ public static ArrayList<Item> getNewItems(List<? extends Item> scheduledFileItems) { ArrayList<Item> newItems = new ArrayList<Item>(); for (Item scheduledFileItem : scheduledFileItems) { if (((LTMItem) scheduledFileItem).isNew()) newItems.add(scheduledFileItem); } return newItems; } public static List<Item> getScheduledItems(List<Item> items) { ArrayList<Item> scheduledItems = new ArrayList<Item>(); for (Item item : items) { if (((LTMItem) item).isScheduledForToday()) { scheduledItems.add(item); } } return scheduledItems; } /** * Returns the difference of two dates in days (fristDay - secondDay). * <p/> * The argument are thereby not assumed to be in any order: the names are just used in order to the ease the * understanding) */ public static int getDayDiff(Date firstDate, Date secondDate) { long fristDay = (int) (firstDate.getTime() / (86400. * 1000.)); long secondDay = (int) (secondDate.getTime() / (86400. * 1000.)); return (int) (fristDay - secondDay); } /** * Computes a measure of urgency given a set of LTM-items. Thereby 'urgency' is defined as the mean of (scheduled * day - today) over all scheduled files. */ public static double getUrgency(ArrayList<Item> items) { double urgency = 0; int numScheduled = 0; for (Item item : items) { LTMItem ltmItem = (LTMItem) item; if (!ltmItem.isScheduledForToday()) continue; Date nextScheduleDate = ltmItem.getNextScheduledDate(); int dayDiff = getDayDiff(getToday(), nextScheduleDate); urgency += dayDiff; numScheduled++; } return (int) (urgency / (double) numScheduled); } @Test public void testDateOperators() { Date christmas2K = (new GregorianCalendar(2000, 11, 23)).getTime(); Date christmas3K = (new GregorianCalendar(3000, 11, 24)).getTime(); Assert.assertTrue(isBeforeToday(christmas2K)); Assert.assertFalse(isToday(christmas2K)); Assert.assertFalse(isBeforeToday(christmas3K)); } }