History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/util/calendar/AbstractCalendar.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/util/calendar/AbstractCalendar.java+398−0
@@ -0,0 +1,398 @@
1+/*
2+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.util.calendar;
27+
28+import java.util.Locale;
29+import java.util.TimeZone;
30+
31+/**
32+ * The <code>AbstractCalendar</code> class provides a framework for
33+ * implementing a concrete calendar system.
34+ *
35+ * <p><a name="fixed_date"></a><B>Fixed Date</B><br>
36+ *
37+ * For implementing a concrete calendar system, each calendar must
38+ * have the common date numbering, starting from midnight the onset of
39+ * Monday, January 1, 1 (Gregorian). It is called a <I>fixed date</I>
40+ * in this class. January 1, 1 (Gregorian) is fixed date 1. (See
41+ * Nachum Dershowitz and Edward M. Reingold, <I>CALENDRICAL
42+ * CALCULATION The Millennium Edition</I>, Section 1.2 for details.)
43+ *
44+ * @author Masayoshi Okutsu
45+ * @since 1.5
46+ */
47+
48+public abstract class AbstractCalendar extends CalendarSystem {
49+
50+ // The constants assume no leap seconds support.
51+ static final int SECOND_IN_MILLIS = 1000;
52+ static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
53+ static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
54+ static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
55+
56+ // The number of days between January 1, 1 and January 1, 1970 (Gregorian)
57+ static final int EPOCH_OFFSET = 719163;
58+
59+ private Era[] eras;
60+
61+ protected AbstractCalendar() {
62+ }
63+
64+ public Era getEra(String eraName) {
65+ if (eras != null) {
66+ for (int i = 0; i < eras.length; i++) {
67+ if (eras[i].equals(eraName)) {
68+ return eras[i];
69+ }
70+ }
71+ }
72+ return null;
73+ }
74+
75+ public Era[] getEras() {
76+ Era[] e = null;
77+ if (eras != null) {
78+ e = new Era[eras.length];
79+ System.arraycopy(eras, 0, e, 0, eras.length);
80+ }
81+ return e;
82+ }
83+
84+ public void setEra(CalendarDate date, String eraName) {
85+ if (eras == null) {
86+ return; // should report an error???
87+ }
88+ for (int i = 0; i < eras.length; i++) {
89+ Era e = eras[i];
90+ if (e != null && e.getName().equals(eraName)) {
91+ date.setEra(e);
92+ return;
93+ }
94+ }
95+ throw new IllegalArgumentException("unknown era name: " + eraName);
96+ }
97+
98+ protected void setEras(Era[] eras) {
99+ this.eras = eras;
100+ }
101+
102+ public CalendarDate getCalendarDate() {
103+ return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
104+ }
105+
106+ public CalendarDate getCalendarDate(long millis) {
107+ return getCalendarDate(millis, newCalendarDate());
108+ }
109+
110+ public CalendarDate getCalendarDate(long millis, TimeZone zone) {
111+ CalendarDate date = newCalendarDate(zone);
112+ return getCalendarDate(millis, date);
113+ }
114+
115+ public CalendarDate getCalendarDate(long millis, CalendarDate date) {
116+ int ms = 0; // time of day
117+ int zoneOffset = 0;
118+ int saving = 0;
119+ long days = 0; // fixed date
120+
121+ // adjust to local time if `date' has time zone.
122+ TimeZone zi = date.getZone();
123+ if (zi != null) {
124+ int[] offsets = new int[2];
125+ if (zi instanceof ZoneInfo) {
126+ zoneOffset = ((ZoneInfo)zi).getOffsets(millis, offsets);
127+ } else {
128+ zoneOffset = zi.getOffset(millis);
129+ offsets[0] = zi.getRawOffset();
130+ offsets[1] = zoneOffset - offsets[0];
131+ }
132+
133+ // We need to calculate the given millis and time zone
134+ // offset separately for java.util.GregorianCalendar
135+ // compatibility. (i.e., millis + zoneOffset could cause
136+ // overflow or underflow, which must be avoided.) Usually
137+ // days should be 0 and ms is in the range of -13:00 to
138+ // +14:00. However, we need to deal with extreme cases.
139+ days = zoneOffset / DAY_IN_MILLIS;
140+ ms = zoneOffset % DAY_IN_MILLIS;
141+ saving = offsets[1];
142+ }
143+ date.setZoneOffset(zoneOffset);
144+ date.setDaylightSaving(saving);
145+
146+ days += millis / DAY_IN_MILLIS;
147+ ms += (int) (millis % DAY_IN_MILLIS);
148+ if (ms >= DAY_IN_MILLIS) {
149+ // at most ms is (DAY_IN_MILLIS - 1) * 2.
150+ ms -= DAY_IN_MILLIS;
151+ ++days;
152+ } else {
153+ // at most ms is (1 - DAY_IN_MILLIS) * 2. Adding one
154+ // DAY_IN_MILLIS results in still negative.
155+ while (ms < 0) {
156+ ms += DAY_IN_MILLIS;
157+ --days;
158+ }
159+ }
160+
161+ // convert to fixed date (offset from Jan. 1, 1 (Gregorian))
162+ days += EPOCH_OFFSET;
163+
164+ // calculate date fields from the fixed date
165+ getCalendarDateFromFixedDate(date, days);
166+
167+ // calculate time fields from the time of day
168+ setTimeOfDay(date, ms);
169+ date.setLeapYear(isLeapYear(date));
170+ date.setNormalized(true);
171+ return date;
172+ }
173+
174+ public long getTime(CalendarDate date) {
175+ long gd = getFixedDate(date);
176+ long ms = (gd - EPOCH_OFFSET) * DAY_IN_MILLIS + getTimeOfDay(date);
177+ int zoneOffset = 0;
178+ TimeZone zi = date.getZone();
179+ if (zi != null) {
180+ if (date.isNormalized()) {
181+ return ms - date.getZoneOffset();
182+ }
183+ // adjust time zone and daylight saving
184+ int[] offsets = new int[2];
185+ if (date.isStandardTime()) {
186+ // 1) 2:30am during starting-DST transition is
187+ // intrepreted as 2:30am ST
188+ // 2) 5:00pm during DST is still interpreted as 5:00pm ST
189+ // 3) 1:30am during ending-DST transition is interpreted
190+ // as 1:30am ST (after transition)
191+ if (zi instanceof ZoneInfo) {
192+ ((ZoneInfo)zi).getOffsetsByStandard(ms, offsets);
193+ zoneOffset = offsets[0];
194+ } else {
195+ zoneOffset = zi.getOffset(ms - zi.getRawOffset());
196+ }
197+ } else {
198+ // 1) 2:30am during starting-DST transition is
199+ // intrepreted as 3:30am DT
200+ // 2) 5:00pm during DST is intrepreted as 5:00pm DT
201+ // 3) 1:30am during ending-DST transition is interpreted
202+ // as 1:30am DT/0:30am ST (before transition)
203+ if (zi instanceof ZoneInfo) {
204+ zoneOffset = ((ZoneInfo)zi).getOffsetsByWall(ms, offsets);
205+ } else {
206+ zoneOffset = zi.getOffset(ms - zi.getRawOffset());
207+ }
208+ }
209+ }
210+ ms -= zoneOffset;
211+ getCalendarDate(ms, date);
212+ return ms;
213+ }
214+
215+ protected long getTimeOfDay(CalendarDate date) {
216+ long fraction = date.getTimeOfDay();
217+ if (fraction != CalendarDate.TIME_UNDEFINED) {
218+ return fraction;
219+ }
220+ fraction = getTimeOfDayValue(date);
221+ date.setTimeOfDay(fraction);
222+ return fraction;
223+ }
224+
225+ public long getTimeOfDayValue(CalendarDate date) {
226+ long fraction = date.getHours();
227+ fraction *= 60;
228+ fraction += date.getMinutes();
229+ fraction *= 60;
230+ fraction += date.getSeconds();
231+ fraction *= 1000;
232+ fraction += date.getMillis();
233+ return fraction;
234+ }
235+
236+ public CalendarDate setTimeOfDay(CalendarDate cdate, int fraction) {
237+ if (fraction < 0) {
238+ throw new IllegalArgumentException();
239+ }
240+ boolean normalizedState = cdate.isNormalized();
241+ int time = fraction;
242+ int hours = time / HOUR_IN_MILLIS;
243+ time %= HOUR_IN_MILLIS;
244+ int minutes = time / MINUTE_IN_MILLIS;
245+ time %= MINUTE_IN_MILLIS;
246+ int seconds = time / SECOND_IN_MILLIS;
247+ time %= SECOND_IN_MILLIS;
248+ cdate.setHours(hours);
249+ cdate.setMinutes(minutes);
250+ cdate.setSeconds(seconds);
251+ cdate.setMillis(time);
252+ cdate.setTimeOfDay(fraction);
253+ if (hours < 24 && normalizedState) {
254+ // If this time of day setting doesn't affect the date,
255+ // then restore the normalized state.
256+ cdate.setNormalized(normalizedState);
257+ }
258+ return cdate;
259+ }
260+
261+ /**
262+ * Returns 7 in this default implementation.
263+ *
264+ * @return 7
265+ */
266+ public int getWeekLength() {
267+ return 7;
268+ }
269+
270+ protected abstract boolean isLeapYear(CalendarDate date);
271+
272+ public CalendarDate getNthDayOfWeek(int nth, int dayOfWeek, CalendarDate date) {
273+ CalendarDate ndate = (CalendarDate) date.clone();
274+ normalize(ndate);
275+ long fd = getFixedDate(ndate);
276+ long nfd;
277+ if (nth > 0) {
278+ nfd = 7 * nth + getDayOfWeekDateBefore(fd, dayOfWeek);
279+ } else {
280+ nfd = 7 * nth + getDayOfWeekDateAfter(fd, dayOfWeek);
281+ }
282+ getCalendarDateFromFixedDate(ndate, nfd);
283+ return ndate;
284+ }
285+
286+ /**
287+ * Returns a date of the given day of week before the given fixed
288+ * date.
289+ *
290+ * @param fixedDate the fixed date
291+ * @param dayOfWeek the day of week
292+ * @return the calculated date
293+ */
294+ static long getDayOfWeekDateBefore(long fixedDate, int dayOfWeek) {
295+ return getDayOfWeekDateOnOrBefore(fixedDate - 1, dayOfWeek);
296+ }
297+
298+ /**
299+ * Returns a date of the given day of week that is closest to and
300+ * after the given fixed date.
301+ *
302+ * @param fixedDate the fixed date
303+ * @param dayOfWeek the day of week
304+ * @return the calculated date
305+ */
306+ static long getDayOfWeekDateAfter(long fixedDate, int dayOfWeek) {
307+ return getDayOfWeekDateOnOrBefore(fixedDate + 7, dayOfWeek);
308+ }
309+
310+ /**
311+ * Returns a date of the given day of week on or before the given fixed
312+ * date.
313+ *
314+ * @param fixedDate the fixed date
315+ * @param dayOfWeek the day of week
316+ * @return the calculated date
317+ */
318+ // public for java.util.GregorianCalendar
319+ public static long getDayOfWeekDateOnOrBefore(long fixedDate, int dayOfWeek) {
320+ long fd = fixedDate - (dayOfWeek - 1);
321+ if (fd >= 0) {
322+ return fixedDate - (fd % 7);
323+ }
324+ return fixedDate - CalendarUtils.mod(fd, 7);
325+ }
326+
327+ /**
328+ * Returns the fixed date calculated with the specified calendar
329+ * date. If the specified date is not normalized, its date fields
330+ * are normalized.
331+ *
332+ * @param date a <code>CalendarDate</code> with which the fixed
333+ * date is calculated
334+ * @return the calculated fixed date
335+ * @see AbstractCalendar.html#fixed_date
336+ */
337+ protected abstract long getFixedDate(CalendarDate date);
338+
339+ /**
340+ * Calculates calendar fields from the specified fixed date. This
341+ * method stores the calculated calendar field values in the specified
342+ * <code>CalendarDate</code>.
343+ *
344+ * @param date a <code>CalendarDate</code> to stored the
345+ * calculated calendar fields.
346+ * @param fixedDate a fixed date to calculate calendar fields
347+ * @see AbstractCalendar.html#fixed_date
348+ */
349+ protected abstract void getCalendarDateFromFixedDate(CalendarDate date,
350+ long fixedDate);
351+
352+ public boolean validateTime(CalendarDate date) {
353+ int t = date.getHours();
354+ if (t < 0 || t >= 24) {
355+ return false;
356+ }
357+ t = date.getMinutes();
358+ if (t < 0 || t >= 60) {
359+ return false;
360+ }
361+ t = date.getSeconds();
362+ // TODO: Leap second support.
363+ if (t < 0 || t >= 60) {
364+ return false;
365+ }
366+ t = date.getMillis();
367+ if (t < 0 || t >= 1000) {
368+ return false;
369+ }
370+ return true;
371+ }
372+
373+
374+ int normalizeTime(CalendarDate date) {
375+ long fraction = getTimeOfDay(date);
376+ long days = 0;
377+
378+ if (fraction >= DAY_IN_MILLIS) {
379+ days = fraction / DAY_IN_MILLIS;
380+ fraction %= DAY_IN_MILLIS;
381+ } else if (fraction < 0) {
382+ days = CalendarUtils.floorDivide(fraction, DAY_IN_MILLIS);
383+ if (days != 0) {
384+ fraction -= DAY_IN_MILLIS * days; // mod(fraction, DAY_IN_MILLIS)
385+ }
386+ }
387+ if (days != 0) {
388+ date.setTimeOfDay(fraction);
389+ }
390+ date.setMillis((int)(fraction % 1000));
391+ fraction /= 1000;
392+ date.setSeconds((int)(fraction % 60));
393+ fraction /= 60;
394+ date.setMinutes((int)(fraction % 60));
395+ date.setHours((int)(fraction / 60));
396+ return (int)days;
397+ }
398+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t