/** * Creates a new date by adding the specified number of months to the base date. * * <p>If the base date is close to the end of the month, the day on the result may be adjusted * slightly: 31 May + 1 month = 30 June. * * @param months the number of months to add (can be negative). * @param base the base date. * @return a new date. */ public static SerialDate addMonths(final int months, final SerialDate base) { final int yy = (12 * base.getYYYY() + base.getMonth() + months - 1) / 12; final int mm = (12 * base.getYYYY() + base.getMonth() + months - 1) % 12 + 1; final int dd = Math.min(base.getDayOfMonth(), SerialDate.lastDayOfMonth(mm, yy)); return SerialDate.createInstance(dd, mm, yy); }
/** * Creates a new date by adding the specified number of years to the base date. * * @param years the number of years to add (can be negative). * @param base the base date. * @return A new date. */ public static SerialDate addYears(final int years, final SerialDate base) { final int baseY = base.getYYYY(); final int baseM = base.getMonth(); final int baseD = base.getDayOfMonth(); final int targetY = baseY + years; final int targetD = Math.min(baseD, SerialDate.lastDayOfMonth(baseM, targetY)); return SerialDate.createInstance(targetD, baseM, targetY); }
/** * Returns the date that falls on the specified day-of-the-week and is CLOSEST to the base date. * * @param targetDOW a code for the target day-of-the-week. * @param base the base date. * @return the date that falls on the specified day-of-the-week and is CLOSEST to the base date. */ public static SerialDate getNearestDayOfWeek(final int targetDOW, final SerialDate base) { // check arguments... if (!SerialDate.isValidWeekdayCode(targetDOW)) { throw new IllegalArgumentException("Invalid day-of-the-week code."); } // find the date... final int baseDOW = base.getDayOfWeek(); int adjust = -Math.abs(targetDOW - baseDOW); if (adjust >= 4) { adjust = 7 - adjust; } if (adjust <= -4) { adjust = 7 + adjust; } return SerialDate.addDays(adjust, base); }
/** * Returns the earliest date that falls on the specified day-of-the-week and is AFTER the base * date. * * @param targetWeekday a code for the target day-of-the-week. * @param base the base date. * @return the earliest date that falls on the specified day-of-the-week and is AFTER the base * date. */ public static SerialDate getFollowingDayOfWeek(final int targetWeekday, final SerialDate base) { // check arguments... if (!SerialDate.isValidWeekdayCode(targetWeekday)) { throw new IllegalArgumentException("Invalid day-of-the-week code."); } // find the date... final int adjust; final int baseDOW = base.getDayOfWeek(); if (baseDOW > targetWeekday) { adjust = 7 + Math.min(0, targetWeekday - baseDOW); } else { adjust = Math.max(0, targetWeekday - baseDOW); } return SerialDate.addDays(adjust, base); }
/** * Converts the date to a string. * * @return a string representation of the date. */ @Override public String toString() { return getDayOfMonth() + "-" + SerialDate.monthCodeToString(getMonth()) + "-" + getYYYY(); }
/** * Rolls the date forward to the last day of the month. * * @param base the base date. * @return a new serial date. */ public SerialDate getEndOfCurrentMonth(final SerialDate base) { final int last = SerialDate.lastDayOfMonth(base.getMonth(), base.getYYYY()); return SerialDate.createInstance(last, base.getMonth(), base.getYYYY()); }
/** * Creates a new date by adding the specified number of days to the base date. * * @param days the number of days to add (can be negative). * @param base the base date. * @return a new date. */ public static SerialDate addDays(final int days, final SerialDate base) { final int serialDayNumber = base.toSerial() + days; return SerialDate.createInstance(serialDayNumber); }