/**
  * 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);
 }
 /**
  * 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]);
   }
 }
 /**
  * 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);
   }
 }
 // -----------------------------------------------------------------------
 public int[] add(ReadablePartial partial, int fieldIndex, int[] values, int valueToAdd) {
   // overridden as superclass algorithm can't handle
   // 2004-02-29 + 48 months -> 2008-02-29 type dates
   if (valueToAdd == 0) {
     return values;
   }
   if (DateTimeUtils.isContiguous(partial)) {
     long instant = 0L;
     for (int i = 0, isize = partial.size(); i < isize; i++) {
       instant = partial.getFieldType(i).getField(iChronology).set(instant, values[i]);
     }
     instant = add(instant, valueToAdd);
     return iChronology.get(partial, instant);
   } else {
     return super.add(partial, fieldIndex, values, valueToAdd);
   }
 }
 /**
  * Is this time interval after the current instant.
  *
  * <p>Intervals are inclusive of the start instant and exclusive of the end.
  *
  * @return true if this time interval is after the current instant
  */
 public boolean isAfterNow() {
   return isAfter(DateTimeUtils.currentTimeMillis());
 }
 /**
  * Is this time interval before the current instant.
  *
  * <p>Intervals are inclusive of the start instant and exclusive of the end.
  *
  * @return true if this time interval is before the current instant
  */
 public boolean isBeforeNow() {
   return isBefore(DateTimeUtils.currentTimeMillis());
 }
 /**
  * Does this time interval contain the current instant.
  *
  * <p>Non-zero duration intervals are inclusive of the start instant and exclusive of the end. A
  * zero duration interval cannot contain anything.
  *
  * @return true if this time interval contains the current instant
  */
 public boolean containsNow() {
   return contains(DateTimeUtils.currentTimeMillis());
 }