Чистый код. Создание, анализ и рефакторинг (Мартин) - страница 271

>606      * к базовой дате.

>607      *

>608      * @param years  количество прибавляемых лет (может быть отрицательным).

>609      * @param base  базовая дата.

>610      *

>611      * @return новая дата.

>612      */

>613     public static SerialDate addYears(final int years, final SerialDate base) {

>614

>615         final int baseY = base.getYYYY();

>616         final int baseM = base.getMonth();

>617         final int baseD = base.getDayOfMonth();

>618

>619         final int targetY = baseY + years;

>620         final int targetD = Math.min(

>621             baseD, SerialDate.lastDayOfMonth(baseM, targetY)

>622         );

>623

>624         return SerialDate.createInstance(targetD, baseM, targetY);

>625

>626     }

>627

>628     /**

>629      * Возвращает последнюю дату, приходящуюся на заданный день недели,

>630      * ПРЕДШЕСТВУЮЩУЮ базовой дате.

>631      *

>632      * @param targetWeekday  код дня недели.

>633      * @param base  базовая дата.

>634      *

>635      * @return последняя дата, приходящаяся на заданный день недели,

>636      *         ПРЕДШЕСТВУЮЩАЯ базовой дате.

>637      */

>638     public static SerialDate getPreviousDayOfWeek(final int targetWeekday,

>639                                                   final SerialDate base) {

>640

>641         // Проверить аргументы...

>642         if (!SerialDate.isValidWeekdayCode(targetWeekday)) {

>643             throw new IllegalArgumentException(

>644                 "Invalid day-of-the-week code."

>645             );

>646         }

>647

>648         // Определить дату...

>649         final int adjust;

>650         final int baseDOW = base.getDayOfWeek();

>651         if (baseDOW > targetWeekday) {

>652             adjust = Math.min(0, targetWeekday - baseDOW);

>653         }

>654         else {

>655             adjust = -7 + Math.max(0, targetWeekday - baseDOW);

>656         }

>657

>658         return SerialDate.addDays(adjust, base);

>659

>660     }

>661

>662     /**

>663      * Возвращает самую раннюю дату, приходящуюся на заданный день недели

>664      * ПОСЛЕ базовой даты.

>665      *

>666      * @param targetWeekday  код дня недели.

>667      * @param base  базовая дата.

>668      *

>669      * @return самая ранняя дата, приходящаяся на заданный день недели

>670      *         ПОСЛЕ базовой даты.

>671      */

>672     public static SerialDate getFollowingDayOfWeek(final int targetWeekday,

>673                                                    final SerialDate base) {

>674

>675         // Проверить аргументы...

>676         if (!SerialDate.isValidWeekdayCode(targetWeekday)) {

>677             throw new IllegalArgumentException(