/** * 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; }
/** * Set the Month component of the specified time instant. * * <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 to month 6 = 06-30 * * <p>03-31 to month 2 = 02-28 or 02-29 depending * * <p> * * @param instant the time instant in millis to update. * @param month the month (1,12) to update the time to. * @return the updated time instant. * @throws IllegalArgumentException if month is invalid */ public long set(long instant, int month) { FieldUtils.verifyValueBounds(this, month, MIN, iMax); // int thisYear = iChronology.getYear(instant); // int thisDom = iChronology.getDayOfMonth(instant, thisYear); int maxDom = iChronology.getDaysInYearMonth(thisYear, month); if (thisDom > maxDom) { // Quietly force DOM to nearest sane value. thisDom = maxDom; } // Return newly calculated millis value return iChronology.getYearMonthDayMillis(thisYear, month, thisDom) + iChronology.getMillisOfDay(instant); }
// ----------------------------------------------------------------------- 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; }