title: Android/Java - Test if date was last month
body: <p>I am working on an app where I store some information between each use, this data essentially boils down to counting the number of times an event has happened today, this week, this month and in the apps lifetime. I store this data in 4 distinct counters I can load/save using SharedPreferences.</p>
  
  <p>Alongside the data I store the "last run time" of the app as a date, my plan was that during load time I will load in the counters then test the stored date against today's date to determine which counters need to be cleared.</p>
  
  <p>Sounds simple right!</p>
  
  <p>After pulling my hair out for a while and going backward and forwards through the Calendar documentation I think I understand them enough to come up with the following:</p>
  
  <pre><code>    Calendar last = Calendar.getInstance();
      last.setTimeInMillis(lastDate);
  
      Calendar today = Calendar.getInstance();
      today.add(Calendar.DATE, -1);
  
      if ( !last.after(today) )
      {
                       today = 0;
      }
  
      today.add(Calendar.WEEK_OF_MONTH, -1);
      today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
  
      if ( !last.after(today) )
      {
                       today = 0;
                       week = 0;
      }
  
      today = Calendar.getInstance();
      today.add(Calendar.MONTH, -1);
      today.set(Calendar.DATE, today.getActualMaximum(Calendar.DATE));
  
      if ( !last.after(today) )
      {
                       today = 0;
                       week = 0;
                       month = 0;
      }   
  </code></pre>
  
  <p>I think this should be fine, however the issue I have is testing, testing today is easy, however testing the month logic would require either waiting a month, or writing a test case which uses the Calendar API to simulate an old date, however I can't write the test case if my assumptions on how the API works was wrong in the first place!</p>
  
  <p>Therefore, after a large wall of text my question is... does the above block of code look sane, or have I completely mis-understood working with dates in Java?</p>
  
  <p>Thanks!</p>
  
  <h2>Edit:</h2>
  
  <p>Second pass at the code:</p>
  
  <p>Does this look any more sensible? If I am understanding things correctly I am now attempting to compare the end of the date that was last saved with the very start of today, this week and this month.</p>
  
  <pre><code>Calendar last = Calendar.getInstance();
      last.setTimeInMillis(lastDate);
  
      last.set(Calendar.HOUR_OF_DAY, last.getActualMaximum(Calendar.HOUR_OF_DAY));
      last.set(Calendar.MINUTE, last.getActualMaximum(Calendar.MINUTE));
      last.set(Calendar.SECOND, last.getActualMaximum(Calendar.SECOND));
      last.set(Calendar.MILLISECOND, last.getActualMaximum(Calendar.MILLISECOND));
  
      Calendar todayStart = Calendar.getInstance();
      todayStart.set(Calendar.HOUR_OF_DAY, todayStart.getActualMinimum(Calendar.HOUR_OF_DAY));
      todayStart.set(Calendar.MINUTE, todayStart.getActualMinimum(Calendar.MINUTE));
      todayStart.set(Calendar.SECOND, todayStart.getActualMinimum(Calendar.SECOND));
      todayStart.set(Calendar.MILLISECOND, todayStart.getActualMinimum(Calendar.MILLISECOND));
  
      // If the last recorded date was before the absolute minimum of today
      if ( last.before(todayStart) )
      {
          todayCount = 0;
      }
  
      Calendar thisWeekStart = Calendar.getInstance();
      thisWeekStart.set(Calendar.HOUR_OF_DAY, thisWeekStart.getActualMinimum(Calendar.HOUR_OF_DAY));
      thisWeekStart.set(Calendar.MINUTE, thisWeekStart.getActualMinimum(Calendar.MINUTE));
      thisWeekStart.set(Calendar.SECOND, thisWeekStart.getActualMinimum(Calendar.SECOND));
      thisWeekStart.set(Calendar.DAY_OF_WEEK, thisWeekStart.getFirstDayOfWeek());
      thisWeekStart.set(Calendar.MILLISECOND, thisWeekStart.getActualMinimum(Calendar.MILLISECOND));
  
      // If the last date was before the absolute minimum of this week then clear
      // this week (and today, just to be on the safe side)
      if ( last.before(thisWeekStart) )
      {
          todayCount = 0;
          weekCount = 0;
      }
  
      Calendar thisMonthStart = Calendar.getInstance();
      thisMonthStart.set(Calendar.HOUR_OF_DAY, thisMonthStart.getActualMinimum(Calendar.HOUR_OF_DAY));
      thisMonthStart.set(Calendar.MINUTE, thisMonthStart.getActualMinimum(Calendar.MINUTE));
      thisMonthStart.set(Calendar.SECOND, thisMonthStart.getActualMinimum(Calendar.SECOND));
      thisMonthStart.set(Calendar.DAY_OF_MONTH, thisMonthStart.getActualMinimum(Calendar.MONTH));
      thisMonthStart.set(Calendar.MILLISECOND, thisMonthStart.getActualMinimum(Calendar.MILLISECOND));
  
      // If the last date was before the absolute minimum of this month then clear month...
      if ( !last.after(thisMonthStart) )
      {
          todayCount = 0;
          weekCount = 0;
          monthCount = 0;
      }   
  </code></pre>