1 /*
2  * Copyright (c) 2013, 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  * @test
26  * @bug 4745761
27  * @summary Unit test for Calendar.Builder.
28  */
29 
30 import java.time.LocalDateTime;
31 import java.util.*;
32 import static java.util.Calendar.*;
33 
34 public class BuilderTest {
35     private static final Locale jaJPJP = new Locale("ja", "JP", "JP");
36     private static final Locale thTH = new Locale("th", "TH");
37     private static final TimeZone LA = TimeZone.getTimeZone("America/Los_Angeles");
38     private static final TimeZone TOKYO = TimeZone.getTimeZone("Asia/Tokyo");
39     private static int error;
40 
main(String[] args)41     public static void main(String[] args) {
42         TimeZone tz = TimeZone.getDefault();
43         Locale loc = Locale.getDefault();
44         try {
45             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
46             Locale.setDefault(Locale.US);
47             Calendar.Builder calb;
48             Calendar cal, expected;
49 
50             // set instant
51             calb = builder();
52             long time = System.currentTimeMillis();
53             cal = calb.setInstant(time).build();
54             expected = new GregorianCalendar();
55             expected.setTimeInMillis(time);
56             check(cal, expected);
57 
58             calb = builder();
59             cal = calb.setInstant(new Date(time)).build();
60             check(cal, expected);
61 
62             // set time zone
63             calb = builder();
64             cal = calb.setTimeZone(LA).setInstant(time).build();
65             expected = new GregorianCalendar(LA, Locale.US);
66             expected.setTimeInMillis(time);
67             check(cal, expected);
68 
69             calb = builder();
70             cal = calb.setTimeZone(TOKYO).setInstant(time).build();
71             expected = new GregorianCalendar(TOKYO, Locale.US);
72             expected.setTimeInMillis(time);
73             check(cal, expected);
74 
75             // set vs. setFields
76             calb = builder();
77             cal = calb.set(YEAR, 2013).set(MONTH, JANUARY).set(DAY_OF_MONTH, 31)
78                       .set(HOUR_OF_DAY, 10).set(MINUTE, 20).set(SECOND, 30).set(MILLISECOND, 40).build();
79             expected = new GregorianCalendar(2013, JANUARY, 31, 10, 20, 30);
80             expected.set(MILLISECOND, 40);
81             check(cal, expected);
82 
83             calb = builder();
84             cal = calb.setFields(YEAR, 2013, MONTH, JANUARY, DAY_OF_MONTH, 31,
85                                  HOUR_OF_DAY, 10, MINUTE, 20, SECOND, 30, MILLISECOND, 40).build();
86             check(cal, expected);
87 
88             // field resolution
89             calb = builder();
90             cal = calb.setFields(YEAR, 2013, MONTH, DECEMBER, DAY_OF_MONTH, 31,
91                                  HOUR_OF_DAY, 10, MINUTE, 20, SECOND, 30, MILLISECOND, 40)
92                       .set(DAY_OF_YEAR, 31).build();  // DAY_OF_YEAR wins.
93             check(cal, expected);
94 
95             // setDate/setTimeOfDay
96             calb = builder();
97             cal = calb.setDate(2013, JANUARY, 31).setTimeOfDay(10, 20, 30, 40).build();
98             check(cal, expected);
99 
100             // week date (ISO 8601)
101             calb = builder().setCalendarType("iso8601");
102             cal = calb.setWeekDate(2013, 1, MONDAY).setTimeOfDay(10, 20, 30).build();
103             expected = getISO8601();
104             expected.set(2012, DECEMBER, 31, 10, 20, 30);
105             check(cal, expected);
106 
107             // default YEAR == 1970
108             cal = builder().setFields(MONTH, JANUARY,
109                                                    DAY_OF_MONTH, 9).build();
110             check(cal, new GregorianCalendar(1970, JANUARY, 9));
111 
112             // no parameters are given.
113             calb = builder();
114             cal = calb.build();
115             expected = new GregorianCalendar();
116             expected.clear();
117             check(cal, expected);
118 
119             // Thai Buddhist calendar
120             calb = builder();
121             cal = calb.setCalendarType("buddhist").setDate(2556, JANUARY, 31).build();
122             expected = Calendar.getInstance(thTH);
123             expected.clear();
124             expected.set(2556, JANUARY, 31);
125             check(cal, expected);
126             // setLocale
127             calb = builder();
128             cal = calb.setLocale(thTH).setDate(2556, JANUARY, 31).build();
129             check(cal, expected);
130 
131             // Japanese Imperial calendar
132             cal = builder().setCalendarType("japanese")
133                 .setFields(YEAR, 1, DAY_OF_YEAR, 1).build();
134             expected = Calendar.getInstance(jaJPJP);
135             expected.clear();
136             if (LocalDateTime.now().isBefore(LocalDateTime.of(2019, 5, 1, 0, 0))) {
137             expected.set(1, JANUARY, 8);
138             } else {
139                 expected.set(1, MAY, 1);
140             }
141             check(cal, expected);
142             // setLocale
143             calb = builder();
144             cal = calb.setLocale(jaJPJP).setFields(YEAR, 1, DAY_OF_YEAR, 1).build();
145             check(cal, expected);
146 
147             testExceptions();
148         } finally {
149             // Restore default Locale and TimeZone
150             Locale.setDefault(loc);
151             TimeZone.setDefault(tz);
152         }
153         if (error > 0) {
154             throw new RuntimeException("Failed");
155         }
156     }
157 
testExceptions()158     private static void testExceptions() {
159         Calendar.Builder calb;
160         Calendar cal;
161 
162         // NPE
163         try {
164             calb = builder().setInstant((Date)null);
165             noException("setInstant((Date)null)");
166         } catch (NullPointerException npe) {
167         }
168         try {
169             calb = builder().setCalendarType(null);
170             noException("setCalendarType(null)");
171         } catch (NullPointerException npe) {
172         }
173         try {
174             calb = builder().setLocale(null);
175             noException("setLocale(null)");
176         } catch (NullPointerException npe) {
177         }
178         try {
179             calb = builder().setTimeZone(null);
180             noException("setTimeZone(null)");
181         } catch (NullPointerException npe) {
182         }
183 
184         // IllegalArgumentException
185         try {
186             // invalid field index in set
187             calb = builder().set(100, 2013);
188             noException("set(100, 2013)");
189         } catch (IllegalArgumentException e) {
190         }
191         try {
192             // invalid field index in setField
193             calb = builder().setFields(100, 2013);
194             noException("setFields(100, 2013)");
195         } catch (IllegalArgumentException e) {
196         }
197         try {
198             // odd number of arguments
199             calb = builder().setFields(YEAR, 2013, MONTH);
200             noException("setFields(YEAR, 2013, MONTH)");
201         } catch (IllegalArgumentException e) {
202         }
203         try {
204             // unknown calendar type
205             calb = builder().setCalendarType("foo");
206             noException("setCalendarType(\"foo\")");
207         } catch (IllegalArgumentException e) {
208         }
209         try {
210             // invalid week definition parameter
211             calb = builder().setWeekDefinition(8, 1);
212             noException("setWeekDefinition(8, 1)");
213         } catch (IllegalArgumentException e) {
214         }
215         try {
216             // invalid week definition parameter
217             calb = builder().setWeekDefinition(SUNDAY, 0);
218             noException("setWeekDefinition(8, 1)");
219         } catch (IllegalArgumentException e) {
220         }
221 
222         try {
223             // sets both instant and field parameters
224             calb = builder().setInstant(new Date()).setDate(2013, JANUARY, 1);
225             noException("setInstant(new Date()).setDate(2013, JANUARY, 1)");
226         } catch (IllegalStateException e) {
227         }
228         try {
229             // sets both field parameters and instant
230             calb = builder().setDate(2013, JANUARY, 1).setInstant(new Date());
231             noException("setDate(2013, JANUARY, 1).setInstant(new Date())");
232         } catch (IllegalStateException e) {
233         }
234         try {
235             // sets inconsistent calendar types
236             calb = builder().setCalendarType("iso8601").setCalendarType("japanese");
237             noException("setCalendarType(\"iso8601\").setCalendarType(\"japanese\")");
238         } catch (IllegalStateException e) {
239         }
240 
241         // IllegalArgumentException in build()
242         calb = nonLenientBuilder().set(MONTH, 100);
243         checkException(calb, IllegalArgumentException.class);
244         calb = nonLenientBuilder().setTimeOfDay(23, 59, 70);
245         checkException(calb, IllegalArgumentException.class);
246         calb = builder().setCalendarType("japanese").setWeekDate(2013, 1, MONDAY);
247         checkException(calb, IllegalArgumentException.class);
248     }
249 
builder()250     private static Calendar.Builder builder() {
251         return new Calendar.Builder();
252     }
253 
nonLenientBuilder()254     private static Calendar.Builder nonLenientBuilder() {
255         return builder().setLenient(false);
256     }
257 
getISO8601()258     private static Calendar getISO8601() {
259         GregorianCalendar cal = new GregorianCalendar();
260         cal.setFirstDayOfWeek(MONDAY);
261         cal.setMinimalDaysInFirstWeek(4);
262         cal.setGregorianChange(new Date(Long.MIN_VALUE));
263         cal.clear();
264         return cal;
265     }
266 
check(Calendar cal, Calendar expected)267     private static void check(Calendar cal, Calendar expected) {
268         if (!cal.equals(expected)) {
269             error++;
270             System.err.println("FAILED:");
271             System.err.println("\t     cal = "+cal.getTime());
272             System.err.println("\texpected = "+expected.getTime());
273             System.err.printf("\tcal = %s%n\texp = %s%n", cal, expected);
274         }
275     }
276 
checkException(Calendar.Builder calb, Class<? extends Exception> exception)277     private static void checkException(Calendar.Builder calb, Class<? extends Exception> exception) {
278         try {
279             Calendar cal = calb.build();
280             error++;
281             System.err.println("expected exception: " + exception);
282         } catch (Exception e) {
283             if (!e.getClass().equals(exception)) {
284                 error++;
285                 System.err.println("unexpected exception: " + e.getClass() + ", expected: " + exception);
286             }
287         }
288     }
289 
noException(String msg)290     private static void noException(String msg) {
291         error++;
292         System.err.println("no exception with "+msg);
293     }
294 }
295