120 calcDayMonthYear();
121 }
122
123 public int getOrdinalDay() {
124 return ordinalDay;
125 }
126
127 public int getYear() {
128 return year;
129 }
130
131 public Month getMonth() {
132 return month;
133 }
134
135 public int getDayOfMonth() {
136 return day;
137 }
138
139 protected Day getDayOfWeekForOrdinalZero() {return Day.SATURDAY;}
140
141 public boolean equals(Object object) {
142 if (!(object instanceof DayDate))
143 return false;
144
145 DayDate date = (DayDate) object;
146 return date.getOrdinalDay() == getOrdinalDay();
147 }
148
149 public int hashCode() {
150 return getOrdinalDay();
151 }
152
153 public int compareTo(Object other) {
154 return daysSince((DayDate) other);
155 }
156
157 private int calcOrdinal(int day, Month month, int year) {
158 int leapDaysForYear = DateUtil.leapYearCount(year - 1);
159 int daysUpToYear = (year - MINIMUM_YEAR_SUPPORTED) * 365 + leapDaysForYear;
160 int daysUpToMonth = AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH[month.toInt()];
161 if (DateUtil.isLeapYear(year) && month.toInt() > FEBRUARY.toInt())
162 daysUpToMonth++;
163 int daysInMonth = day - 1;
164 return daysUpToYear + daysUpToMonth + daysInMonth + EARLIEST_DATE_ORDINAL;
165 }
166
167 private void calcDayMonthYear() {
168 int days = ordinalDay - EARLIEST_DATE_ORDINAL;
169 int overestimatedYear = MINIMUM_YEAR_SUPPORTED + days / 365;
170 int nonleapdays = days - DateUtil.leapYearCount(overestimatedYear);
171 int underestimatedYear = MINIMUM_YEAR_SUPPORTED + nonleapdays / 365;
172
173 year = huntForYearContaining(ordinalDay, underestimatedYear);
174 int firstOrdinalOfYear = firstOrdinalOfYear(year);
175 month = huntForMonthContaining(ordinalDay, firstOrdinalOfYear);
176 day = ordinalDay - firstOrdinalOfYear - daysBeforeThisMonth(month.toInt());
177 }
178
179 private Month huntForMonthContaining(int anOrdinal, int firstOrdinalOfYear) {
180 int daysIntoThisYear = anOrdinal - firstOrdinalOfYear;
181 int aMonth = 1;
182 while (daysBeforeThisMonth(aMonth) < daysIntoThisYear)
183 aMonth++;
184
185 return Month.fromInt(aMonth - 1);
186 }
187
188 private int daysBeforeThisMonth(int aMonth) {
189 if (DateUtil.isLeapYear(year))
190 return LEAP_YEAR_AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH[aMonth] - 1;
191 else
192 return AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH[aMonth] - 1;
193 }
194