// -----------------------------------------------------------------------
 public boolean isLeap(long instant) {
   int thisYear = iChronology.getYear(instant);
   if (iChronology.isLeapYear(thisYear)) {
     return (iChronology.getMonthOfYear(instant, thisYear) == iLeapMonth);
   }
   return false;
 }
  /**
   * Add the specified month to the specified time instant. The amount added may be negative.
   *
   * <p>If the new month has less total days than the specified day of the month, this value is
   * coerced to the nearest sane value. e.g.
   *
   * <p>07-31 - (1 month) = 06-30
   *
   * <p>03-31 - (1 month) = 02-28 or 02-29 depending
   *
   * <p>
   *
   * @see org.joda.time.DateTimeField#add
   * @see org.joda.time.ReadWritableDateTime#addMonths(int)
   * @param instant the time instant in millis to update.
   * @param months the months to add (can be negative).
   * @return the updated time instant.
   */
  public long add(long instant, int months) {
    if (months == 0) {
      return instant; // the easy case
    }
    //
    // Save time part first.
    //
    long timePart = iChronology.getMillisOfDay(instant);
    //
    //
    // Get this year and month.
    //
    int thisYear = iChronology.getYear(instant);
    int thisMonth = iChronology.getMonthOfYear(instant, thisYear);
    // ----------------------------------------------------------
    //
    // Do not refactor without careful consideration.
    // Order of calculation is important.
    //
    int yearToUse;
    // Initially, monthToUse is zero-based
    int monthToUse = thisMonth - 1 + months;
    if (monthToUse >= 0) {
      yearToUse = thisYear + (monthToUse / iMax);
      monthToUse = (monthToUse % iMax) + 1;
    } else {
      yearToUse = thisYear + (monthToUse / iMax) - 1;
      monthToUse = Math.abs(monthToUse);
      int remMonthToUse = monthToUse % iMax;
      // Take care of the boundary condition
      if (remMonthToUse == 0) {
        remMonthToUse = iMax;
      }
      monthToUse = iMax - remMonthToUse + 1;
      // Take care of the boundary condition
      if (monthToUse == 1) {
        yearToUse += 1;
      }
    }
    // End of do not refactor.
    // ----------------------------------------------------------

    //
    // Quietly force DOM to nearest sane value.
    //
    int dayToUse = iChronology.getDayOfMonth(instant, thisYear, thisMonth);
    int maxDay = iChronology.getDaysInYearMonth(yearToUse, monthToUse);
    if (dayToUse > maxDay) {
      dayToUse = maxDay;
    }
    //
    // get proper date part, and return result
    //
    long datePart = iChronology.getYearMonthDayMillis(yearToUse, monthToUse, dayToUse);
    return datePart + timePart;
  }
  // -----------------------------------------------------------------------
  public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
    if (minuendInstant < subtrahendInstant) {
      return -getDifference(subtrahendInstant, minuendInstant);
    }

    int minuendYear = iChronology.getYear(minuendInstant);
    int minuendMonth = iChronology.getMonthOfYear(minuendInstant, minuendYear);
    int subtrahendYear = iChronology.getYear(subtrahendInstant);
    int subtrahendMonth = iChronology.getMonthOfYear(subtrahendInstant, subtrahendYear);

    long difference =
        (minuendYear - subtrahendYear) * ((long) iMax) + minuendMonth - subtrahendMonth;

    // Before adjusting for remainder, account for special case of add
    // where the day-of-month is forced to the nearest sane value.
    int minuendDom = iChronology.getDayOfMonth(minuendInstant, minuendYear, minuendMonth);
    if (minuendDom == iChronology.getDaysInYearMonth(minuendYear, minuendMonth)) {
      // Last day of the minuend month...
      int subtrahendDom =
          iChronology.getDayOfMonth(subtrahendInstant, subtrahendYear, subtrahendMonth);
      if (subtrahendDom > minuendDom) {
        // ...and day of subtrahend month is larger.
        // Note: This works fine, but it ideally shouldn't invoke other
        // fields from within a field.
        subtrahendInstant = iChronology.dayOfMonth().set(subtrahendInstant, minuendDom);
      }
    }

    // Inlined remainder method to avoid duplicate calls.
    long minuendRem = minuendInstant - iChronology.getYearMonthMillis(minuendYear, minuendMonth);
    long subtrahendRem =
        subtrahendInstant - iChronology.getYearMonthMillis(subtrahendYear, subtrahendMonth);

    if (minuendRem < subtrahendRem) {
      difference--;
    }

    return difference;
  }
  // -----------------------------------------------------------------------
  public long add(long instant, long months) {
    int i_months = (int) months;
    if (i_months == months) {
      return add(instant, i_months);
    }

    // Copied from add(long, int) and modified slightly:

    long timePart = iChronology.getMillisOfDay(instant);

    int thisYear = iChronology.getYear(instant);
    int thisMonth = iChronology.getMonthOfYear(instant, thisYear);

    long yearToUse;
    long monthToUse = thisMonth - 1 + months;
    if (monthToUse >= 0) {
      yearToUse = thisYear + (monthToUse / iMax);
      monthToUse = (monthToUse % iMax) + 1;
    } else {
      yearToUse = thisYear + (monthToUse / iMax) - 1;
      monthToUse = Math.abs(monthToUse);
      int remMonthToUse = (int) (monthToUse % iMax);
      if (remMonthToUse == 0) {
        remMonthToUse = iMax;
      }
      monthToUse = iMax - remMonthToUse + 1;
      if (monthToUse == 1) {
        yearToUse += 1;
      }
    }

    if (yearToUse < iChronology.getMinYear() || yearToUse > iChronology.getMaxYear()) {

      throw new IllegalArgumentException("Magnitude of add amount is too large: " + months);
    }

    int i_yearToUse = (int) yearToUse;
    int i_monthToUse = (int) monthToUse;

    int dayToUse = iChronology.getDayOfMonth(instant, thisYear, thisMonth);
    int maxDay = iChronology.getDaysInYearMonth(i_yearToUse, i_monthToUse);
    if (dayToUse > maxDay) {
      dayToUse = maxDay;
    }

    long datePart = iChronology.getYearMonthDayMillis(i_yearToUse, i_monthToUse, dayToUse);
    return datePart + timePart;
  }
 /**
  * Get the Month component of the specified time instant.
  *
  * @see org.joda.time.DateTimeField#get(long)
  * @see org.joda.time.ReadableDateTime#getMonthOfYear()
  * @param instant the time instant in millis to query.
  * @return the month extracted from the input.
  */
 public int get(long instant) {
   return iChronology.getMonthOfYear(instant);
 }
 // -----------------------------------------------------------------------
 public long roundFloor(long instant) {
   int year = iChronology.getYear(instant);
   int month = iChronology.getMonthOfYear(instant, year);
   return iChronology.getYearMonthMillis(year, month);
 }