/**
  * Is this time interval entirely after the specified interval.
  *
  * <p>Intervals are inclusive of the start instant and exclusive of the end. Only the end time of
  * the specified interval is used in the comparison.
  *
  * @param interval the interval to compare to, null means now
  * @return true if this time interval is after the interval specified
  */
 public boolean isAfter(ReadableInterval interval) {
   long endMillis;
   if (interval == null) {
     endMillis = DateTimeUtils.currentTimeMillis();
   } else {
     endMillis = interval.getEndMillis();
   }
   return (getStartMillis() >= endMillis);
 }
 /**
  * Does this time interval contain the specified time interval.
  *
  * <p>Non-zero duration intervals are inclusive of the start instant and exclusive of the end. The
  * other interval is contained if this interval wholly contains, starts, finishes or equals it. A
  * zero duration interval cannot contain anything.
  *
  * <p>When two intervals are compared the result is one of three states: (a) they abut, (b) there
  * is a gap between them, (c) they overlap. The <code>contains</code> method is not related to
  * these states. In particular, a zero duration interval is contained at the start of a larger
  * interval, but does not overlap (it abuts instead).
  *
  * <p>For example:
  *
  * <pre>
  * [09:00 to 10:00) contains [09:00 to 10:00)  = true
  * [09:00 to 10:00) contains [09:00 to 09:30)  = true
  * [09:00 to 10:00) contains [09:30 to 10:00)  = true
  * [09:00 to 10:00) contains [09:15 to 09:45)  = true
  * [09:00 to 10:00) contains [09:00 to 09:00)  = true
  *
  * [09:00 to 10:00) contains [08:59 to 10:00)  = false (otherStart before thisStart)
  * [09:00 to 10:00) contains [09:00 to 10:01)  = false (otherEnd after thisEnd)
  * [09:00 to 10:00) contains [10:00 to 10:00)  = false (otherStart equals thisEnd)
  *
  * [14:00 to 14:00) contains [14:00 to 14:00)  = false (zero duration contains nothing)
  * </pre>
  *
  * Passing in a <code>null</code> parameter will have the same effect as calling {@link
  * #containsNow()}.
  *
  * @param interval the time interval to compare to, null means a zero duration interval now
  * @return true if this time interval contains the time interval
  */
 public boolean contains(ReadableInterval interval) {
   if (interval == null) {
     return containsNow();
   }
   long otherStart = interval.getStartMillis();
   long otherEnd = interval.getEndMillis();
   long thisStart = getStartMillis();
   long thisEnd = getEndMillis();
   return (thisStart <= otherStart && otherStart < thisEnd && otherEnd <= thisEnd);
 }
 /**
  * Compares this object with the specified object for equality based on start and end millis plus
  * the chronology. All ReadableInterval instances are accepted.
  *
  * <p>To compare the duration of two time intervals, use {@link #toDuration()} to get the
  * durations and compare those.
  *
  * @param readableInterval a readable interval to check against
  * @return true if the intervals are equal comparing the start millis, end millis and chronology
  */
 public boolean equals(Object readableInterval) {
   if (this == readableInterval) {
     return true;
   }
   if (readableInterval instanceof ReadableInterval == false) {
     return false;
   }
   ReadableInterval other = (ReadableInterval) readableInterval;
   return getStartMillis() == other.getStartMillis()
       && getEndMillis() == other.getEndMillis()
       && FieldUtils.equals(getChronology(), other.getChronology());
 }
 /**
  * Does this time interval overlap the specified time interval.
  *
  * <p>Intervals are inclusive of the start instant and exclusive of the end. An interval overlaps
  * another if it shares some common part of the datetime continuum.
  *
  * <p>When two intervals are compared the result is one of three states: (a) they abut, (b) there
  * is a gap between them, (c) they overlap. The abuts state takes precedence over the other two,
  * thus a zero duration interval at the start of a larger interval abuts and does not overlap.
  *
  * <p>For example:
  *
  * <pre>
  * [09:00 to 10:00) overlaps [08:00 to 08:30)  = false (completely before)
  * [09:00 to 10:00) overlaps [08:00 to 09:00)  = false (abuts before)
  * [09:00 to 10:00) overlaps [08:00 to 09:30)  = true
  * [09:00 to 10:00) overlaps [08:00 to 10:00)  = true
  * [09:00 to 10:00) overlaps [08:00 to 11:00)  = true
  *
  * [09:00 to 10:00) overlaps [09:00 to 09:00)  = false (abuts before)
  * [09:00 to 10:00) overlaps [09:00 to 09:30)  = true
  * [09:00 to 10:00) overlaps [09:00 to 10:00)  = true
  * [09:00 to 10:00) overlaps [09:00 to 11:00)  = true
  *
  * [09:00 to 10:00) overlaps [09:30 to 09:30)  = true
  * [09:00 to 10:00) overlaps [09:30 to 10:00)  = true
  * [09:00 to 10:00) overlaps [09:30 to 11:00)  = true
  *
  * [09:00 to 10:00) overlaps [10:00 to 10:00)  = false (abuts after)
  * [09:00 to 10:00) overlaps [10:00 to 11:00)  = false (abuts after)
  *
  * [09:00 to 10:00) overlaps [10:30 to 11:00)  = false (completely after)
  *
  * [14:00 to 14:00) overlaps [14:00 to 14:00)  = false (abuts before and after)
  * [14:00 to 14:00) overlaps [13:00 to 15:00)  = true
  * </pre>
  *
  * @param interval the time interval to compare to, null means a zero length interval now
  * @return true if the time intervals overlap
  */
 public boolean overlaps(ReadableInterval interval) {
   long thisStart = getStartMillis();
   long thisEnd = getEndMillis();
   if (interval == null) {
     long now = DateTimeUtils.currentTimeMillis();
     return (thisStart < now && now < thisEnd);
   } else {
     long otherStart = interval.getStartMillis();
     long otherEnd = interval.getEndMillis();
     return (thisStart < otherEnd && otherStart < thisEnd);
   }
 }
 /**
  * Is this interval equal to the specified interval ignoring the chronology.
  *
  * <p>This compares the underlying instants, ignoring the chronology.
  *
  * @param other a readable interval to check against
  * @return true if the intervals are equal comparing the start and end millis
  * @since 2.3
  */
 public boolean isEqual(ReadableInterval other) {
   return getStartMillis() == other.getStartMillis() && getEndMillis() == other.getEndMillis();
 }