1 55 56 package org.jfree.date; 57 58 import java.util.Calendar ; 59 import java.util.Date ; 60 61 81 public class SpreadsheetDate extends SerialDate { 82 83 84 private static final long serialVersionUID = -2039586705374454461L; 85 86 90 private final int serial; 91 92 93 private final int day; 94 95 96 private final int month; 97 98 99 private final int year; 100 101 108 public SpreadsheetDate(final int day, final int month, final int year) { 109 110 if ((year >= 1900) && (year <= 9999)) { 111 this.year = year; 112 } 113 else { 114 throw new IllegalArgumentException ( 115 "The 'year' argument must be in range 1900 to 9999." 116 ); 117 } 118 119 if ((month >= MonthConstants.JANUARY) 120 && (month <= MonthConstants.DECEMBER)) { 121 this.month = month; 122 } 123 else { 124 throw new IllegalArgumentException ( 125 "The 'month' argument must be in the range 1 to 12." 126 ); 127 } 128 129 if ((day >= 1) && (day <= SerialDate.lastDayOfMonth(month, year))) { 130 this.day = day; 131 } 132 else { 133 throw new IllegalArgumentException ("Invalid 'day' argument."); 134 } 135 136 this.serial = calcSerial(day, month, year); 138 139 } 140 141 147 public SpreadsheetDate(final int serial) { 148 149 if ((serial >= SERIAL_LOWER_BOUND) && (serial <= SERIAL_UPPER_BOUND)) { 150 this.serial = serial; 151 } 152 else { 153 throw new IllegalArgumentException ( 154 "SpreadsheetDate: Serial must be in range 2 to 2958465."); 155 } 156 157 final int days = this.serial - SERIAL_LOWER_BOUND; 160 final int overestimatedYYYY = 1900 + (days / 365); 162 final int leaps = SerialDate.leapYearCount(overestimatedYYYY); 163 final int nonleapdays = days - leaps; 164 int underestimatedYYYY = 1900 + (nonleapdays / 365); 166 167 if (underestimatedYYYY == overestimatedYYYY) { 168 this.year = underestimatedYYYY; 169 } 170 else { 171 int ss1 = calcSerial(1, 1, underestimatedYYYY); 172 while (ss1 <= this.serial) { 173 underestimatedYYYY = underestimatedYYYY + 1; 174 ss1 = calcSerial(1, 1, underestimatedYYYY); 175 } 176 this.year = underestimatedYYYY - 1; 177 } 178 179 final int ss2 = calcSerial(1, 1, this.year); 180 181 int[] daysToEndOfPrecedingMonth 182 = AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH; 183 184 if (isLeapYear(this.year)) { 185 daysToEndOfPrecedingMonth 186 = LEAP_YEAR_AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH; 187 } 188 189 int mm = 1; 191 int sss = ss2 + daysToEndOfPrecedingMonth[mm] - 1; 192 while (sss < this.serial) { 193 mm = mm + 1; 194 sss = ss2 + daysToEndOfPrecedingMonth[mm] - 1; 195 } 196 this.month = mm - 1; 197 198 this.day = this.serial - ss2 200 - daysToEndOfPrecedingMonth[this.month] + 1; 201 202 } 203 204 211 public int toSerial() { 212 return this.serial; 213 } 214 215 220 public Date toDate() { 221 final Calendar calendar = Calendar.getInstance(); 222 calendar.set(getYYYY(), getMonth() - 1, getDayOfMonth(), 0, 0, 0); 223 return calendar.getTime(); 224 } 225 226 231 public int getYYYY() { 232 return this.year; 233 } 234 235 240 public int getMonth() { 241 return this.month; 242 } 243 244 249 public int getDayOfMonth() { 250 return this.day; 251 } 252 253 263 public int getDayOfWeek() { 264 return (this.serial + 6) % 7 + 1; 265 } 266 267 278 public boolean equals(final Object object) { 279 280 if (object instanceof SerialDate) { 281 final SerialDate s = (SerialDate) object; 282 return (s.toSerial() == this.toSerial()); 283 } 284 else { 285 return false; 286 } 287 288 } 289 290 295 public int hashCode() { 296 return toSerial(); 297 } 298 299 308 public int compare(final SerialDate other) { 309 return this.serial - other.toSerial(); 310 } 311 312 320 public int compareTo(final Object other) { 321 return compare((SerialDate) other); 322 } 323 324 333 public boolean isOn(final SerialDate other) { 334 return (this.serial == other.toSerial()); 335 } 336 337 346 public boolean isBefore(final SerialDate other) { 347 return (this.serial < other.toSerial()); 348 } 349 350 359 public boolean isOnOrBefore(final SerialDate other) { 360 return (this.serial <= other.toSerial()); 361 } 362 363 372 public boolean isAfter(final SerialDate other) { 373 return (this.serial > other.toSerial()); 374 } 375 376 385 public boolean isOnOrAfter(final SerialDate other) { 386 return (this.serial >= other.toSerial()); 387 } 388 389 399 public boolean isInRange(final SerialDate d1, final SerialDate d2) { 400 return isInRange(d1, d2, SerialDate.INCLUDE_BOTH); 401 } 402 403 416 public boolean isInRange(final SerialDate d1, final SerialDate d2, 417 final int include) { 418 final int s1 = d1.toSerial(); 419 final int s2 = d2.toSerial(); 420 final int start = Math.min(s1, s2); 421 final int end = Math.max(s1, s2); 422 423 final int s = toSerial(); 424 if (include == SerialDate.INCLUDE_BOTH) { 425 return (s >= start && s <= end); 426 } 427 else if (include == SerialDate.INCLUDE_FIRST) { 428 return (s >= start && s < end); 429 } 430 else if (include == SerialDate.INCLUDE_SECOND) { 431 return (s > start && s <= end); 432 } 433 else { 434 return (s > start && s < end); 435 } 436 } 437 438 449 private int calcSerial(final int d, final int m, final int y) { 450 final int yy = ((y - 1900) * 365) + SerialDate.leapYearCount(y - 1); 451 int mm = SerialDate.AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH[m]; 452 if (m > MonthConstants.FEBRUARY) { 453 if (SerialDate.isLeapYear(y)) { 454 mm = mm + 1; 455 } 456 } 457 final int dd = d; 458 return yy + mm + dd + 1; 459 } 460 461 } 462 | Popular Tags |