1 /*
   2  * Copyright (c) 2003, 2016, 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 = new Locale("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 }