javajodatime

How to check if a list of intervals (Joda-Time) fully covers a month in Java


I'm using Joda-Time library in Java to keep track a list of time intervals. I want to check if a list of Interval objects fully covers every minute of a month. There's about 30 intervals of varying length from a few hours to a few days.

I thought a cheap way to do this is to sort the list of intervals by start time, then successively check if there is a break between the intervals within the range of the month. If yes, then the month is not fully covered.

I'm stuck on the first part, sorting the list. I planned to use Arrays.sort(), but it needs the elements to implement the comparable interface. However, after looking through the source, Joda-Time's Interval class doesn't seem to have one I can override, and I can't extend it to write my own compareTo method.

Other than writing my own sorting method, anyone know an easier way to accomplish this? Thanks


Solution

  • You can use next method

    static boolean covers(Interval month, List<Interval> intervals)
    {
      //assumes intervals are sorted already on start times
      final MutableInterval monthInterval = new MutableInterval(month);
      start: for (final Interval interval : intervals)
      {
         if (interval.getStartMillis() <= monthInterval.getStartMillis()
            && interval.getEndMillis() > monthInterval.getStartMillis())
         {
            if (interval.getEndMillis() > monthInterval.getEndMillis())
            {
               return true;
            }
            monthInterval.setStartMillis(interval.getEndMillis());
            // continue start;  // loop continues regardless
         } else {
               if (interval.overlaps(month)) return false;
         }
      }
      return monthInterval.getStartMillis()== monthInterval.getEndMillis();
    } 
    

    Example

       static final List<Interval> intervals = new ArrayList<Interval>();
       static
       {
          intervals.add(new Interval(new DateTime(1990, 05, 15, 00, 00, 00, 00), new DateTime(1990, 05, 18, 00, 00, 00, 00)));
          intervals.add(new Interval(new DateTime(1990, 04, 28, 00, 00, 00, 00), new DateTime(1990, 05, 18, 00, 00, 00, 00)));
          intervals.add(new Interval(new DateTime(1990, 05, 17, 00, 00, 00, 00), new DateTime(1990, 05, 21, 00, 00, 00, 00)));
          intervals.add(new Interval(new DateTime(1990, 05, 21, 00, 00, 00, 00), new DateTime(1990, 05, 29, 00, 00, 00, 00)));
          intervals.add(new Interval(new DateTime(1990, 05, 22, 00, 00, 00, 00), new DateTime(1990, 05, 25, 00, 00, 00, 00)));
          intervals.add(new Interval(new DateTime(1990, 05, 27, 00, 00, 00, 00), new DateTime(1990, 06, 02, 00, 00, 00, 00)));
       }
    
       public static void main(String[] args)
       {
          final DateTime startOfMonth = new DateTime(1990, 05, 01, 00, 00);
          final Interval monthInterval = new Interval(startOfMonth, startOfMonth.plusMonths(1));
    
          covers(monthInterval, intervals);
       }
    
       static boolean covers(Interval month, List<Interval> intervals)
       {
          final MutableInterval monthInterval = new MutableInterval(month);
          start: for (final Interval interval : intervals)
          {
             if (interval.getStartMillis() <= monthInterval.getStartMillis()
                && interval.getEndMillis() > monthInterval.getStartMillis())
             {
                if (interval.getEndMillis() > monthInterval.getStartMillis())
                {
                   return true;
                }
                monthInterval.setStartMillis(interval.getEndMillis());
                continue start;
             }
          }
          return monthInterval.getStartMillis()== monthInterval.getEndMillis();
       }