/**
  * Extracts interval endpoint values from an object of this converter's type, and sets them into
  * the given ReadWritableInterval.
  *
  * @param writableInterval interval to get modified, not null
  * @param object the object to convert, must not be null
  * @param chrono the chronology to use, may be null
  * @throws ClassCastException if the object is invalid
  */
 public void setInto(ReadWritableInterval writableInterval, Object object, Chronology chrono) {
   ReadableInterval input = (ReadableInterval) object;
   writableInterval.setInterval(input);
   if (chrono != null) {
     writableInterval.setChronology(chrono);
   } else {
     writableInterval.setChronology(input.getChronology());
   }
 }
 /**
  * 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);
 }
 /**
  * Sets the values of the mutable duration from the specified interval.
  *
  * @param writablePeriod the period to modify
  * @param object the interval to set from
  * @param chrono the chronology to use
  */
 public void setInto(ReadWritablePeriod writablePeriod, Object object, Chronology chrono) {
   ReadableInterval interval = (ReadableInterval) object;
   chrono = (chrono != null ? chrono : DateTimeUtils.getIntervalChronology(interval));
   long start = interval.getStartMillis();
   long end = interval.getEndMillis();
   int[] values = chrono.get(writablePeriod, start, end);
   for (int i = 0; i < values.length; i++) {
     writablePeriod.setValue(i, values[i]);
   }
 }
 /**
  * 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 start and end millis are equal
  */
 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 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);
 }
 /**
  * Is this time interval entirely before the specified instant.
  *
  * <p>Intervals are inclusive of the start instant and exclusive of the end.
  *
  * @param interval the interval to compare to, null means now
  * @return true if this time interval is before the interval specified
  */
 public boolean isBefore(ReadableInterval interval) {
   if (interval == null) {
     return isBeforeNow();
   }
   return isBefore(interval.getStartMillis());
 }