1 /*
2  * Copyright (c) 2007, 2019, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 import java.util.Calendar;
26 import sun.util.calendar.CalendarUtils;
27 
28 public class CalendarAdapter extends Calendar {
29     public static enum Type {
30         GREGORIAN, BUDDHIST, JAPANESE;
31     }
32 
33     static final String[] FIELD_NAMES = {
34         "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
35         "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
36         "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
37         "DST_OFFSET"
38     };
39 
40     Calendar cal;
41     GregorianAdapter gcal;
42     private Type type;
43 
CalendarAdapter(Calendar cal)44     public CalendarAdapter(Calendar cal) {
45         if (cal == null)
46             throw new NullPointerException();
47 
48         this.cal = cal;
49         if (cal instanceof sun.util.BuddhistCalendar) {
50             type = Type.BUDDHIST;
51         } else if (cal instanceof GregorianAdapter) {
52             type = Type.GREGORIAN;
53             gcal = (GregorianAdapter) cal;
54         } else {
55             type = Type.JAPANESE;
56         }
57     }
58 
setFirstDayOfWeek(int w)59     public void setFirstDayOfWeek(int w) {
60         cal.setFirstDayOfWeek(w);
61     }
62 
getFirstDayOfWeek()63     public int getFirstDayOfWeek() {
64         return cal.getFirstDayOfWeek();
65     }
66 
setMinimalDaysInFirstWeek(int value)67     public void setMinimalDaysInFirstWeek(int value) {
68         cal.setMinimalDaysInFirstWeek(value);
69     }
70 
getMinimalDaysInFirstWeek()71     public int getMinimalDaysInFirstWeek() {
72         return getMinimalDaysInFirstWeek();
73     }
74 
getTimeInMillis()75     public long getTimeInMillis() {
76         return cal.getTimeInMillis();
77     }
78 
setTimeInMillis(long millis)79     public void setTimeInMillis(long millis) {
80         cal.setTimeInMillis(millis);
81     }
82 
get(int field)83     public int get(int field) {
84         return cal.get(field);
85     }
86 
set(int field, int value)87     public void set(int field, int value) {
88         cal.set(field, value);
89     }
90 
add(int field, int amount)91     public void add(int field, int amount) {
92         cal.add(field, amount);
93     }
94 
roll(int field, boolean dir)95     public void roll(int field, boolean dir) {
96         cal.roll(field, dir);
97     }
98 
roll(int field, int amount)99     public void roll(int field, int amount) {
100         cal.roll(field, amount);
101     }
102 
setDate(int year, int month, int date)103     public void setDate(int year, int month, int date)
104     {
105         cal.set(year, month, date);
106     }
107 
setDate(int era, int year, int month, int date)108     public void setDate(int era, int year, int month, int date) {
109         cal.set(ERA, era);
110         cal.set(year, month, date);
111     }
112 
setDateTime(int year, int month, int date, int hourOfDay, int minute, int second)113     public void setDateTime(int year, int month, int date, int hourOfDay, int minute, int second)
114     {
115         cal.set(year, month, date, hourOfDay, minute, second);
116     }
117 
clearAll()118     public void clearAll() {
119         cal.clear();
120     }
121 
clearField(int field)122     public void clearField(int field)
123     {
124         cal.clear(field);
125     }
126 
isSetField(int field)127     public boolean isSetField(int field)
128     {
129         return cal.isSet(field);
130     }
131 
getMaximum(int field)132     public int getMaximum(int field) {
133         return cal.getMaximum(field);
134     }
135 
getLeastMaximum(int field)136     public int getLeastMaximum(int field) {
137         return cal.getLeastMaximum(field);
138     }
139 
getActualMaximum(int field)140     public int getActualMaximum(int field) {
141         return cal.getActualMaximum(field);
142     }
143 
getMinimum(int field)144     public int getMinimum(int field) {
145         return cal.getMinimum(field);
146     }
147 
getGreatestMinimum(int field)148     public int getGreatestMinimum(int field) {
149         return cal.getGreatestMinimum(field);
150     }
151 
getActualMinimum(int field)152     public int getActualMinimum(int field) {
153         return cal.getActualMinimum(field);
154     }
155 
setLenient(boolean lenient)156     public void setLenient(boolean lenient) {
157         cal.setLenient(lenient);
158     }
159 
toString()160     public String toString() {
161         return cal.toString();
162     }
163 
computeFields()164     protected void computeFields() {
165     }
166 
computeTime()167     protected void computeTime() {
168     }
169 
setTimeOfDay(int hourOfDay, int minute, int second, int ms)170     void setTimeOfDay(int hourOfDay, int minute, int second, int ms) {
171         cal.set(HOUR_OF_DAY, hourOfDay);
172         cal.set(MINUTE, minute);
173         cal.set(SECOND, second);
174         cal.set(MILLISECOND, ms);
175     }
176 
177     // GregorianAdapter specific methods
178 
179     // When gcal is null, the methods throw a NPE.
180 
getSetStateFields()181     int getSetStateFields() {
182         return gcal.getSetStateFields();
183     }
184 
getFields()185     int[] getFields() {
186         return gcal.getFields();
187     }
188 
checkInternalDate(int year, int month, int dayOfMonth)189     boolean checkInternalDate(int year, int month, int dayOfMonth) {
190         return gcal.checkInternalDate(year, month, dayOfMonth);
191     }
192 
checkInternalDate(int year, int month, int dayOfMonth, int dayOfWeek)193     boolean checkInternalDate(int year, int month, int dayOfMonth, int dayOfWeek) {
194         return gcal.checkInternalDate(year, month, dayOfMonth, dayOfWeek);
195     }
196 
checkInternalField(int field, int expectedValue)197     boolean checkInternalField(int field, int expectedValue) {
198         return checkInternalField(field, expectedValue);
199     }
200 
201     // check methods
202 
checkAllSet()203     boolean checkAllSet() {
204         initTest();
205         for (int i = 0; i < FIELD_COUNT; i++) {
206             checkFieldState(i, true);
207         }
208         return getStatus();
209     }
210 
checkMaximum(int field, int expectedValue)211     boolean checkMaximum(int field, int expectedValue) {
212         int val;
213         if ((val = getMaximum(field)) != expectedValue) {
214             appendMessage("getMaximum("+FIELD_NAMES[field]+"): got " + val
215                           + " expected " + expectedValue);
216         }
217         return getStatus();
218     }
219 
checkActualMaximum(int field, int expectedValue)220     boolean checkActualMaximum(int field, int expectedValue) {
221         int val;
222         if ((val = getActualMaximum(field)) != expectedValue) {
223             appendMessage("getActualMaximum("+FIELD_NAMES[field]+"): got " + val
224                           + " expected " + expectedValue);
225         }
226         return getStatus();
227     }
228 
checkLeastMaximum(int field, int expectedValue)229     boolean checkLeastMaximum(int field, int expectedValue) {
230         int val;
231         if ((val = getLeastMaximum(field)) != expectedValue) {
232             appendMessage("getLeastMaximum("+FIELD_NAMES[field]+"): got " + val
233                           + " expected " + expectedValue);
234         }
235         return getStatus();
236     }
237 
checkMinimum(int field, int expectedValue)238     boolean checkMinimum(int field, int expectedValue) {
239         int val;
240         if ((val = getMinimum(field)) != expectedValue) {
241             appendMessage("getMinimum("+FIELD_NAMES[field]+"): got " + val
242                           + " expected " + expectedValue);
243         }
244         return getStatus();
245     }
246 
checkActualMinimum(int field, int expectedValue)247     boolean checkActualMinimum(int field, int expectedValue) {
248         int val;
249         if ((val = getActualMinimum(field)) != expectedValue) {
250             appendMessage("getActualMinimum("+FIELD_NAMES[field]+"): got " + val
251                           + " expected " + expectedValue);
252         }
253         return getStatus();
254     }
255 
checkGreatestMinimum(int field, int expectedValue)256     boolean checkGreatestMinimum(int field, int expectedValue) {
257         int val;
258         if ((val = getGreatestMinimum(field)) != expectedValue) {
259             appendMessage("getGreatestMinimum("+FIELD_NAMES[field]+"): got " + val
260                           + " expected " + expectedValue);
261         }
262         return getStatus();
263     }
264 
checkDate(int year, int month, int dayOfMonth)265     boolean checkDate(int year, int month, int dayOfMonth) {
266         initTest();
267         checkField(YEAR, year);
268         checkField(MONTH, month);
269         checkField(DAY_OF_MONTH, dayOfMonth);
270         return getStatus();
271     }
272 
checkDate(int era, int year, int month, int dayOfMonth)273     boolean checkDate(int era, int year, int month, int dayOfMonth) {
274         initTest();
275         checkField(ERA, era);
276         checkField(YEAR, year);
277         checkField(MONTH, month);
278         checkField(DAY_OF_MONTH, dayOfMonth);
279         return getStatus();
280     }
281 
checkDateTime(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)282     boolean checkDateTime(int year, int month, int dayOfMonth,
283                           int hourOfDay, int minute, int second) {
284         initTest();
285         checkField(YEAR, year);
286         checkField(MONTH, month);
287         checkField(DAY_OF_MONTH, dayOfMonth);
288         checkField(HOUR_OF_DAY, hourOfDay);
289         checkField(MINUTE, minute);
290         checkField(SECOND, second);
291         return getStatus();
292     }
293 
checkDateTime(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second, int ms)294     boolean checkDateTime(int year, int month, int dayOfMonth,
295                           int hourOfDay, int minute, int second, int ms) {
296         initTest();
297         checkField(YEAR, year);
298         checkField(MONTH, month);
299         checkField(DAY_OF_MONTH, dayOfMonth);
300         checkField(HOUR_OF_DAY, hourOfDay);
301         checkField(MINUTE, minute);
302         checkField(SECOND, second);
303         checkField(MILLISECOND, ms);
304         return getStatus();
305     }
306 
checkTimeOfDay(int hourOfDay, int minute, int second, int ms)307     boolean checkTimeOfDay(int hourOfDay, int minute, int second, int ms) {
308         initTest();
309         checkField(HOUR_OF_DAY, hourOfDay);
310         checkField(MINUTE, minute);
311         checkField(SECOND, second);
312         checkField(MILLISECOND, ms);
313         return getStatus();
314     }
315 
checkMillis(long millis)316     boolean checkMillis(long millis) {
317         initTest();
318         long t = cal.getTimeInMillis();
319         if (t != millis) {
320             appendMessage("wrong millis: got " + t + ", expected " + millis);
321             return false;
322         }
323         return true;
324     }
325 
checkFieldState(int field, boolean expectedState)326     boolean checkFieldState(int field, boolean expectedState) {
327         if (isSet(field) != expectedState) {
328             appendMessage(FIELD_NAMES[field] + " state is not " + expectedState + "; ");
329             return false;
330         }
331         return true;
332     }
333 
checkField(int field, int expectedValue)334     boolean checkField(int field, int expectedValue) {
335         int val;
336         if ((val = get(field)) != expectedValue) {
337             appendMessage("get(" + FIELD_NAMES[field] + "): got " + val +
338                           ", expected " + expectedValue + "; ");
339             return false;
340         }
341         return true;
342     }
343 
fieldName(int field)344     static final String fieldName(int field) {
345         return FIELD_NAMES[field];
346     }
347 
toDateString()348     String toDateString() {
349         StringBuffer sb = new StringBuffer();
350         String[] eraNames = null;
351         switch (type) {
352         case GREGORIAN:
353             eraNames = new String[] { "BCE", "" };
354             break;
355 
356         case BUDDHIST:
357             eraNames = new String[] { "Before BE", "BE"};
358             break;
359 
360         case JAPANESE:
361             eraNames = new String[] {
362                 "BeforeMeiji",
363                 "Meiji",
364                 "Taisho",
365                 "Showa",
366                 "Heisei",
367                 "Reiwa"
368             };
369             break;
370         }
371 
372         sb.append(eraNames[cal.get(ERA)]);
373         if (sb.length() > 0)
374             sb.append(' ');
375         CalendarUtils.sprintf0d(sb, cal.get(YEAR), 4).append('-');
376         CalendarUtils.sprintf0d(sb, cal.get(MONTH)+1, 2).append('-');
377         CalendarUtils.sprintf0d(sb, cal.get(DAY_OF_MONTH), 2);
378         return sb.toString();
379     }
380 
toTimeString()381     String toTimeString() {
382         StringBuffer sb = new StringBuffer();
383         CalendarUtils.sprintf0d(sb, cal.get(HOUR_OF_DAY), 2).append(':');
384         CalendarUtils.sprintf0d(sb, cal.get(MINUTE), 2).append(':');
385         CalendarUtils.sprintf0d(sb, cal.get(SECOND),2 ).append('.');
386         CalendarUtils.sprintf0d(sb, cal.get(MILLISECOND), 3);
387         int zoneOffset = cal.get(ZONE_OFFSET) + cal.get(DST_OFFSET);
388         if (zoneOffset == 0) {
389             sb.append('Z');
390         } else {
391             int offset;
392             char sign;
393             if (zoneOffset > 0) {
394                 offset = zoneOffset;
395                 sign = '+';
396             } else {
397                 offset = -zoneOffset;
398                 sign = '-';
399             }
400             offset /= 60000;
401             sb.append(sign);
402             CalendarUtils.sprintf0d(sb, offset / 60, 2);
403             CalendarUtils.sprintf0d(sb, offset % 60, 2);
404         }
405         return sb.toString();
406     }
407 
toDateTimeString()408     String toDateTimeString() {
409         return toDateString() + "T" + toTimeString();
410     }
411 
412     // Message handling
413 
414     StringBuffer msg = new StringBuffer();
415 
initTest()416     private void initTest() {
417         msg = new StringBuffer();
418     }
419 
getMessage()420     String getMessage() {
421         String s = msg.toString();
422         msg = new StringBuffer();
423         return "    " + s;
424     }
425 
setMessage(String msg)426     private void setMessage(String msg) {
427         this.msg = new StringBuffer(msg);
428     }
429 
appendMessage(String msg)430     private void appendMessage(String msg) {
431         this.msg.append(msg);
432     }
433 
getStatus()434     boolean getStatus() {
435         return msg.length() == 0;
436     }
437 }
438