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

>  45  * смещение в днях от фиксированной точки отсчета.

>  46  *

>  47  *  Почему не использовать java.util.Date? Будем использовать, где это имеет смысл.

>  48  *  Класс java.util.Date бывает *слишком* точным - он представляет момент

>  49  *  времени с точностью до 1/100 секунды (при этом сама дата зависит от часового

>  50  *  пояса). Иногда бывает нужно просто представить конкретный день (скажем,

>  51  *  21 января 2015), не заботясь о времени суток, часовом поясе и т.д.

>  52  *  Именно для таких ситуаций определяется класс DayDate.

>  53  *

>  54  * Для создания экземпляра используется DayDateFactory.makeDate.

>  55  *

>  56  * @author Дэвид Гилберт

>  57  * @author Роберт С. Мартин провел значительную переработку.

>  58  */

>  59

>  60 public abstract class DayDate implements Comparable, Serializable {

>  61   public abstract int getOrdinalDay();

>  62   public abstract int getYear();

>  63   public abstract Month getMonth();

>  64   public abstract int getDayOfMonth();

>  65

>  66   protected abstract Day getDayOfWeekForOrdinalZero();

>  67

>  68   public DayDate plusDays(int days) {

>  69     return DayDateFactory.makeDate(getOrdinalDay() + days);

>  70   }

>  71

>  72   public DayDate plusMonths(int months) {

>  73     int thisMonthAsOrdinal = getMonth().toInt() - Month.JANUARY.toInt();

>  74     int thisMonthAndYearAsOrdinal = 12 * getYear() + thisMonthAsOrdinal;

>  75     int resultMonthAndYearAsOrdinal = thisMonthAndYearAsOrdinal + months;

>  76     int resultYear = resultMonthAndYearAsOrdinal / 12;

>  77     int resultMonthAsOrdinal = resultMonthAndYearAsOrdinal % 12 + Month.JANUARY.

>         toInt();

>  78     Month resultMonth = Month.fromInt(resultMonthAsOrdinal);

>  79     int resultDay = correctLastDayOfMonth(getDayOfMonth(), resultMonth, resultYear);

>  80     return DayDateFactory.makeDate(resultDay, resultMonth, resultYear);

>  81   }

>  82

>  83   public DayDate plusYears(int years) {

>  84     int resultYear = getYear() + years;

>  85     int resultDay = correctLastDayOfMonth(getDayOfMonth(), getMonth(), resultYear);

>  86     return DayDateFactory.makeDate(resultDay, getMonth(), resultYear);

>  87   }

>  88

>  89   private int correctLastDayOfMonth(int day, Month month, int year) {

>  90     int lastDayOfMonth = DateUtil.lastDayOfMonth(month, year);

>  91     if (day > lastDayOfMonth)

>  92         day = lastDayOfMonth;

>  93     return day;

>  94   }

>  95

>  96   public DayDate getPreviousDayOfWeek(Day targetDayOfWeek) {

>  97     int offsetToTarget = targetDayOfWeek.toInt() - getDayOfWeek().toInt();

>  98     if (offsetToTarget >= 0)