1 /*
  2  * Copyright (c) 2003, 2022, 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 4817812 4847186 4956227 4956479
 27  * @summary Confirm that BuddhistCalendar's add(), roll() and toString() work correctly with Buddhist Era years.
 28  */
 29 
 30 import java.util.Calendar;
 31 import java.util.GregorianCalendar;
 32 import java.util.Locale;
 33 import static java.util.Calendar.*;
 34 
 35 public class BuddhistCalendarTest {
 36 
 37     private static final Locale THAI_LOCALE = Locale.of("th", "TH");
 38 
 39     public static void main(String[] args) {
 40         testAddRoll();
 41         testToString();
 42         testException();
 43         testLeastMax();
 44     }
 45 
 46     /**
 47      * 4817812
 48      */
 49     static void testAddRoll() {
 50         Calendar cal;
 51         int base, year;
 52 
 53         /*
 54          * Test: BuddhistCalendar.add(YEAR)
 55          */
 56         cal = getBuddhistCalendar();
 57         base = cal.get(YEAR);
 58         cal.add(YEAR, 1);
 59         year = cal.get(YEAR);
 60         check(year, base+1, "add(+YEAR)");
 61 
 62         cal = getBuddhistCalendar();
 63         base = cal.get(YEAR);
 64         cal.add(YEAR, -3);
 65         year = cal.get(YEAR);
 66         check(year, base-3, "add(-YEAR)");
 67 
 68         /*
 69          * Test BuddhistCalendar.add(MONTH)
 70          */
 71         cal = getBuddhistCalendar();
 72         base = cal.get(YEAR);
 73         cal.set(MONTH, DECEMBER);
 74         cal.add(MONTH, 2);
 75         year = cal.get(YEAR);
 76         check(year, base+1, "add(+MONTH)");
 77 
 78         cal = getBuddhistCalendar();
 79         base = cal.get(YEAR);
 80         cal.set(MONTH, FEBRUARY);
 81         cal.add(MONTH, -4);
 82         year = cal.get(YEAR);
 83         check(year, base-1, "add(-MONTH)");
 84 
 85         /*
 86          * Test BuddhistCalendar.roll(YEAR)
 87          */
 88         cal = getBuddhistCalendar();
 89         base = cal.get(YEAR);
 90         cal.roll(YEAR, 2);
 91         year = cal.get(YEAR);
 92         check(year, base+2, "roll(+YEAR)");
 93 
 94         cal = getBuddhistCalendar();
 95         base = cal.get(YEAR);
 96         cal.roll(YEAR, -4);
 97         year = cal.get(YEAR);
 98         check(year, base-4, "roll(-YEAR)");
 99 
100         /*
101          * Test BuddhistCalendar.roll(WEEK_OF_YEAR)
102          */
103         cal = getBuddhistCalendar();
104         cal.set(YEAR, 2543);   // A.D.2000
105         cal.set(MONTH, DECEMBER);
106         cal.set(DATE, 31);
107         base = cal.get(YEAR);
108         check(base, 2543, "roll(+WEEK_OF_YEAR)");
109         cal.roll(WEEK_OF_YEAR, 10);
110         year = cal.get(YEAR);
111         check(year, base, "roll(+WEEK_OF_YEAR)");
112 
113         cal = getBuddhistCalendar();
114         cal.set(YEAR, 2543);   // A.D.2000
115         cal.set(MONTH, JANUARY);
116         cal.set(DATE, 1);
117         base = cal.get(YEAR);
118         check(base, 2543, "roll(+WEEK_OF_YEAR)");
119         cal.roll(WEEK_OF_YEAR, -10);
120         year = cal.get(YEAR);
121         check(year, base, "roll(-WEEK_OF_YEAR)");
122 
123         /*
124          * Test Calendar.set(year, month, date)
125          */
126         cal = getBuddhistCalendar();
127         base = cal.get(YEAR);
128         cal.set(3001, APRIL, 10);
129         year = cal.get(YEAR);
130         check(year, 3001, "set(year, month, date)");
131 
132         /*
133          * Test Calendar.set(year, month, date, hour, minute)
134          */
135         cal = getBuddhistCalendar();
136         base = cal.get(YEAR);
137         cal.set(3020, MAY, 20, 9, 10);
138         year = cal.get(YEAR);
139         check(year, 3020, "set(year, month, date, hour, minute)");
140 
141         /*
142          * Test Calendar.set(year, month, date, hour, minute, second)
143          */
144         cal = getBuddhistCalendar();
145         base = cal.get(YEAR);
146         cal.set(3120, MAY, 20, 9, 10, 52);
147         year = cal.get(YEAR);
148         check(year, 3120, "set(year, month, date, hour, minute, second)");
149 
150         /*
151          * Test BuddhistCalendar.getActualMaximum(YEAR);
152          *    set(YEAR)/get(YEAR) in this method doesn't affect the real
153          *    YEAR value because a clone is used with set()&get().
154          */
155         cal = getBuddhistCalendar();
156         base = cal.get(YEAR);
157         int limit = cal.getActualMaximum(YEAR);
158         year = cal.get(YEAR);
159         check(year, base, "BuddhistCalendar.getActualMaximum(YEAR)");
160 
161         /*
162          * Test BuddhistCalendar.getActualMinimum(YEAR);
163          *   This doesn't call set(YEAR) nor get(YEAR), though.
164          */
165         cal = getBuddhistCalendar();
166         base = cal.get(YEAR);
167         limit = cal.getActualMinimum(YEAR);
168         year = cal.get(YEAR);
169         check(year, base, "BuddhistCalendar.getActualMinimum(YEAR)");
170     }
171 
172     /**
173      * 4847186: BuddhistCalendar: toString() returns Gregorian year
174      */
175     static void testToString() {
176         Calendar cal = getBuddhistCalendar();
177         int year = cal.get(YEAR);
178         String s = cal.toString();
179         String y = s.replaceAll(".+,YEAR=(\\d+),.+", "$1");
180         if (Integer.parseInt(y) != year) {
181             throw new RuntimeException("toString(): wrong year value: got " + y
182                                        + ", expected " + year);
183         }
184     }
185 
186     /**
187      * 4956479: BuddhistCalendar methods may return wrong values after exception
188      */
189     static void testException() {
190         Calendar cal = getBuddhistCalendar();
191         int year = cal.get(YEAR);
192         boolean exceptionOccurred = false;
193         try {
194             cal.add(100, +1); // cause exception
195         } catch (Exception e) {
196             exceptionOccurred = true;
197         }
198         if (!exceptionOccurred) {
199             throw new RuntimeException("testException: test case failed: no exception thrown");
200         }
201         int year2 = cal.get(YEAR);
202         if (year2 != year) {
203             throw new RuntimeException("wrong year value after exception: got " + year2
204                                        + ", expected " + year);
205         }
206     }
207 
208     /**
209      * 4956227: getLeastMaximum(WEEK_OF_MONTH) return diff. val. for Greg. and Buddhist Calendar
210      */
211     static void testLeastMax() {
212         Calendar bc = getBuddhistCalendar();
213         // Specify THAI_LOCALE to get the same params for WEEK
214         // calculations (6904680).
215         Calendar gc = new GregorianCalendar(THAI_LOCALE);
216         for (int f = 0; f < Calendar.FIELD_COUNT; f++) {
217             if (f == ERA || f == YEAR) {
218                 continue;
219             }
220             int bn = bc.getLeastMaximum(f);
221             int gn = gc.getLeastMaximum(f);
222             if (bn != gn) {
223                 throw new RuntimeException("inconsistent Least Max value for " + Koyomi.getFieldName(f)
224                                            + ": Buddhist=" + bn
225                                            + ": Gregorian=" + gn);
226             }
227         }
228     }
229 
230     /**
231      * @return a BuddhistCalendar
232      */
233     static Calendar getBuddhistCalendar() {
234         return Calendar.getInstance(THAI_LOCALE);
235     }
236 
237     static void check(int got, int expected, String s) {
238         if (got != expected) {
239             throw new RuntimeException("Failed: " +
240                 s + ": got:" + got + ", expected:" + expected);
241         }
242     }
243 }