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)
99 offsetToTarget -= 7;
100 return plusDays(offsetToTarget);
101 }
102
103 public DayDate getFollowingDayOfWeek(Day targetDayOfWeek) {
104 int offsetToTarget = targetDayOfWeek.toInt() - getDayOfWeek().toInt();
105 if (offsetToTarget <= 0)
106 offsetToTarget += 7;
107 return plusDays(offsetToTarget);
108 }
109
110 public DayDate getNearestDayOfWeek(Day targetDayOfWeek) {
111 int offsetToThisWeeksTarget = targetDayOfWeek.toInt() - getDayOfWeek().
toInt();
112 int offsetToFutureTarget = (offsetToThisWeeksTarget + 7) % 7;
113 int offsetToPreviousTarget = offsetToFutureTarget - 7;
114
115 if (offsetToFutureTarget > 3)
116 return plusDays(offsetToPreviousTarget);
117 else
118 return plusDays(offsetToFutureTarget);
119 }
120
121 public DayDate getEndOfMonth() {
122 Month month = getMonth();
123 int year = getYear();