63 * в Microsoft Excel. Поддерживаемый диапазон дат:
64 * с 1 января 1900 по 31 декабря 9999.
65 *
66 * Учтите, что в Excel существует намеренная ошибка, вследствие которой год
67 * 1900 считается високосным, тогда как в действительности он таковым не является.
68 * Дополнительная информация приведена на сайте Microsoft в статье Q181370:
69 *
70 * http://support.microsoft.com/support/kb/articles/Q181/3/70.asp
71 *
72 * По правилам Excel 1 января 1900 = 1. По правилам этого класса
73 * 1 января 1900 = 2.
74 * В результате номер дня этого класса будет отличаться от номера Excel
75 * в январе и феврале 1900...но затем Excel прибавляет лишний день
76 * (29 февраля 1900, который в действительности не существует!), и с этого
77 * момента нумерация дней совпадает.
78 *
79 * @author David Gilbert
80 */
81 public class SpreadsheetDate extends DayDate {
82 public static final int EARLIEST_DATE_ORDINAL = 2; // 1/1/1900
83 public static final int LATEST_DATE_ORDINAL = 2958465; // 12/31/9999
84 public static final int MINIMUM_YEAR_SUPPORTED = 1900;
85 public static final int MAXIMUM_YEAR_SUPPORTED = 9999;
86 static final int[] AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH =
87 {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
88 static final int[] LEAP_YEAR_AGGREGATE_DAYS_TO_END_OF_PRECEDING_MONTH =
89 {0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
90
91 private int ordinalDay;
92 private int day;
93 private Month month;
94 private int year;
95
96 public SpreadsheetDate(int day, Month month, int year) {
97 if (year < MINIMUM_YEAR_SUPPORTED || year > MAXIMUM_YEAR_SUPPORTED)
98 throw new IllegalArgumentException(
99 "The 'year' argument must be in range " +
100 MINIMUM_YEAR_SUPPORTED + " to " + MAXIMUM_YEAR_SUPPORTED + ".");
101 if (day < 1 || day > DateUtil.lastDayOfMonth(month, year))
102 throw new IllegalArgumentException("Invalid 'day' argument.");
103
104 this.year = year;
105 this.month = month;
106 this.day = day;
107 ordinalDay = calcOrdinal(day, month, year);
108 }
109
110 public SpreadsheetDate(int day, int month, int year) {
111 this(day, Month.fromInt(month), year);
112 }
113
114 public SpreadsheetDate(int serial) {
115 if (serial < EARLIEST_DATE_ORDINAL || serial > LATEST_DATE_ORDINAL)
116 throw new IllegalArgumentException(
117 "SpreadsheetDate: Serial must be in range 2 to 2958465.");
118
119 ordinalDay = serial;