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 4359204 4928615 4743587 4956232 6459836 6549953 27 * @library /java/text/testlib 28 * @build Koyomi 29 * @run main GregorianCutoverTest 30 * @summary Unit tests related to the Gregorian cutover support. 31 */ 32 33 import java.util.Date; 34 import java.util.Locale; 35 import java.util.TimeZone; 36 37 import static java.util.GregorianCalendar.*; 38 39 public class GregorianCutoverTest extends IntlTest { 40 41 public static void main(String[] args) throws Exception { 42 TimeZone tz = TimeZone.getDefault(); 43 Locale lc = Locale.getDefault(); 44 try { 45 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); 46 Locale.setDefault(Locale.US); 47 48 new GregorianCutoverTest().run(args); 49 } finally { 50 TimeZone.setDefault(tz); 51 Locale.setDefault(lc); 52 } 53 } 54 55 /** 56 * 4359204: GregorianCalendar.get(cal.DAY_OF_YEAR) is inconsistent for year 1582 57 */ 58 public void Test4359204() { 59 Koyomi cal = new Koyomi(); 60 61 cal.set(1582, JANUARY, 1); 62 checkContinuity(cal, DAY_OF_YEAR); 63 checkContinuity(cal, WEEK_OF_YEAR); 64 cal.set(1582, OCTOBER, 1); 65 checkContinuity(cal, WEEK_OF_MONTH); 66 67 // JCK tests the cutover date 1970-1-1 (Epoch) 68 cal.setGregorianChange(new Date(0)); 69 cal.set(1969, JANUARY, 1); 70 checkContinuity(cal, DAY_OF_YEAR); 71 checkContinuity(cal, WEEK_OF_YEAR); 72 cal.set(1969, DECEMBER, 1); 73 checkContinuity(cal, WEEK_OF_MONTH); 74 cal.set(1970, JANUARY, 1); 75 checkContinuity(cal, DAY_OF_YEAR); 76 checkContinuity(cal, WEEK_OF_YEAR); 77 78 // Use large date (year >= 50000) 79 cal.setGregorianChange(new Date(50000-1900, JANUARY, 20)); 80 cal.set(49998, JANUARY, 1); 81 checkContinuity(cal, DAY_OF_YEAR); 82 checkContinuity(cal, WEEK_OF_YEAR); 83 cal.set(49999, JANUARY, 1); 84 checkContinuity(cal, DAY_OF_YEAR); 85 checkContinuity(cal, WEEK_OF_YEAR); 86 cal.set(50000, JANUARY, 20); 87 checkContinuity(cal, DAY_OF_YEAR); 88 checkContinuity(cal, WEEK_OF_YEAR); 89 90 // Handling of "overlapping" dates may still be incorrect as 91 // of 1.5. Also, there's no way to disambiguate "overlapping" 92 // dates. 93 // millis=-112033929600000: date=-1581-10-15T00:00:00.000Z 94 cal.setGregorianChange(new Date(-112033929600000L)); 95 cal.set(ERA, AD); 96 cal.set(-1581, JANUARY, 1); 97 // The year should have 379 days. 98 checkContinuity(cal, DAY_OF_YEAR); 99 checkContinuity(cal, WEEK_OF_YEAR); 100 101 logln("Default cutover"); 102 cal = new Koyomi(); 103 cal.set(1582, OCTOBER, 1); 104 logln(" roll --DAY_OF_MONTH from 1582/10/01"); 105 cal.roll(DAY_OF_MONTH, -1); 106 if (!cal.checkDate(1582, OCTOBER, 31)) { 107 errln(cal.getMessage()); 108 } 109 logln(" roll DAY_OF_MONTH+10 from 1582/10/31"); 110 cal.roll(DAY_OF_MONTH, +10); 111 if (!cal.checkDate(1582, OCTOBER, 20)) { 112 errln(cal.getMessage()); 113 } 114 logln(" roll DAY_OF_MONTH-10 from 1582/10/20"); 115 cal.roll(DAY_OF_MONTH, -10); 116 if (!cal.checkDate(1582, OCTOBER, 31)) { 117 errln(cal.getMessage()); 118 } 119 logln(" roll back one day further"); 120 cal.roll(DAY_OF_MONTH, +1); 121 if (!cal.checkDate(1582, OCTOBER, 1)) { 122 errln(cal.getMessage()); 123 } 124 125 // should handle the gap between 1969/12/22 (Julian) to 1970/1/5 (Gregorian) 126 logln("Cutover date is 1970/1/5"); 127 cal.setGregorianChange(new Date(1970-1900, JANUARY, 5)); 128 cal.set(ERA, AD); 129 cal.set(YEAR, 1970); 130 logln(" Set DAY_OF_YEAR to the 28th day of 1970"); 131 cal.set(DAY_OF_YEAR, 28); 132 if (!cal.checkDate(1970, FEBRUARY, 1)) { 133 errln(cal.getMessage()); 134 } 135 if (!cal.checkFieldValue(WEEK_OF_YEAR, 5)) { 136 errln(cal.getMessage()); 137 } 138 logln(" 1969/12/22 should be the 356th day of the year."); 139 cal.set(1969, DECEMBER, 22); 140 if (!cal.checkFieldValue(DAY_OF_YEAR, 356)) { 141 errln(cal.getMessage()); 142 } 143 logln(" Set DAY_OF_YEAR to autual maximum."); 144 int actualMaxDayOfYear = cal.getActualMaximum(DAY_OF_YEAR); 145 if (actualMaxDayOfYear != 356) { 146 errln("actual maximum of DAY_OF_YEAR: got " + actualMaxDayOfYear + ", expected 356"); 147 } 148 cal.set(DAY_OF_YEAR, actualMaxDayOfYear); 149 if (!cal.checkDate(1969, DECEMBER, 22)) { 150 errln(cal.getMessage()); 151 } 152 cal.set(1969, DECEMBER, 22); 153 cal.roll(DAY_OF_YEAR, +1); 154 logln(" Set to 1969/12/22 and roll DAY_OF_YEAR++"); 155 if (!cal.checkDate(1969, JANUARY, 1)) { 156 errln(cal.getMessage()); 157 } 158 logln(" 1970/1/5 should be the first day of the year."); 159 cal.set(1970, JANUARY, 5); 160 if (!cal.checkFieldValue(DAY_OF_YEAR, 1)) { 161 errln(cal.getMessage()); 162 } 163 logln(" roll --DAY_OF_MONTH from 1970/1/5"); 164 cal.roll(DAY_OF_MONTH, -1); 165 if (!cal.checkDate(1970, JANUARY, 31)) { 166 errln(cal.getMessage()); 167 } 168 logln(" roll back one day of month"); 169 cal.roll(DAY_OF_MONTH, +1); 170 if (!cal.checkDate(1970, JANUARY, 5)) { 171 errln(cal.getMessage()); 172 } 173 174 // Test "missing" dates in non-lenient. 175 cal = new Koyomi(); // new instance for the default cutover 176 cal.setLenient(false); 177 try { 178 // the next day of 1582/10/4 (Julian) is 1582/10/15 (Gregorian) 179 logln("1582/10/10 doesn't exit with the default cutover."); 180 cal.set(1582, OCTOBER, 10); 181 cal.getTime(); 182 errln(" Didn't throw IllegalArgumentException in non-lenient."); 183 } catch (IllegalArgumentException e) { 184 } 185 } 186 187 private void checkContinuity(Koyomi cal, int field) { 188 cal.getTime(); 189 logln(Koyomi.getFieldName(field) + " starting on " + cal.toDateString()); 190 int max = cal.getActualMaximum(field); 191 for (int i = 1; i <= max; i++) { 192 logln(i + " " + cal.toDateString()); 193 if (!cal.checkFieldValue(field, i)) { 194 errln(" " + cal.toDateString() + ":\t" + cal.getMessage()); 195 } 196 cal.add(field, +1); 197 } 198 } 199 200 /** 201 * 4928615: GregorianCalendar returns wrong dates after setGregorianChange 202 */ 203 public void Test4928615() { 204 Koyomi cal = new Koyomi(); 205 logln("Today is 2003/10/1 Gregorian."); 206 Date x = new Date(2003-1900, 10-1, 1); 207 cal.setTime(x); 208 209 logln(" Changing the cutover date to yesterday..."); 210 cal.setGregorianChange(new Date(x.getTime() - (24*3600*1000))); 211 if (!cal.checkDate(2003, OCTOBER, 1)) { 212 errln(" " + cal.getMessage()); 213 } 214 logln(" Changing the cutover date to tomorrow..."); 215 cal.setGregorianChange(new Date(x.getTime() + (24*3600*1000))); 216 if (!cal.checkDate(2003, SEPTEMBER, 18)) { 217 errln(" " + cal.getMessage()); 218 } 219 } 220 221 /** 222 * 4743587: GregorianCalendar.getLeastMaximum() returns wrong values 223 */ 224 public void Test4743587() { 225 Koyomi cal = new Koyomi(); 226 Koyomi cal2 = (Koyomi) cal.clone(); 227 logln("getLeastMaximum should handle cutover year.\n" 228 +" default cutover date"); 229 if (!cal.checkLeastMaximum(DAY_OF_YEAR, 365-10)) { 230 errln(" " + cal.getMessage()); 231 } 232 if (!cal.checkLeastMaximum(WEEK_OF_YEAR, 52-((10+6)/7))) { 233 errln(" " + cal.getMessage()); 234 } 235 // Corrected for 4956232 236 if (!cal.checkLeastMaximum(DAY_OF_MONTH, 28)) { 237 errln(" " + cal.getMessage()); 238 } 239 if (!cal.checkLeastMaximum(WEEK_OF_MONTH, 3)) { 240 errln(" " + cal.getMessage()); 241 } 242 if (!cal.checkLeastMaximum(DAY_OF_WEEK_IN_MONTH, 3)) { 243 errln(" " + cal.getMessage()); 244 } 245 // make sure that getLeastMaximum calls didn't affect the date 246 if (!cal.equals(cal2)) { 247 errln(" getLeastMaximum calls modified the object."); 248 } 249 if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 1)) { 250 errln(" " + cal.getMessage()); 251 } 252 253 logln(" changing the date to 1582/10/20 for actual min/max tests"); 254 cal.set(1582, OCTOBER, 20); 255 if (!cal.checkActualMinimum(DAY_OF_MONTH, 1)) { 256 errln(" " + cal.getMessage()); 257 } 258 if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { 259 errln(" " + cal.getMessage()); 260 } 261 262 cal = new Koyomi(); 263 logln("Change the cutover date to 1970/1/5."); 264 cal.setGregorianChange(new Date(1970-1900, 0, 5)); 265 if (!cal.checkLeastMaximum(DAY_OF_YEAR, 356)) { 266 errln(" " + cal.getMessage()); 267 } 268 if (!cal.checkLeastMaximum(DAY_OF_MONTH, 22)) { 269 errln(" " + cal.getMessage()); 270 } 271 if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 5)) { 272 errln(" " + cal.getMessage()); 273 } 274 cal.set(1970, JANUARY, 10); 275 if (!cal.checkActualMinimum(DAY_OF_MONTH, 5)) { 276 errln(" " + cal.getMessage()); 277 } 278 if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { 279 errln(" " + cal.getMessage()); 280 } 281 } 282 283 /** 284 * 6459836: (cal) GregorianCalendar set method provides wrong result 285 */ 286 public void Test6459836() { 287 int hour = 13865672; 288 Koyomi gc1 = new Koyomi(); 289 gc1.clear(); 290 gc1.set(1, gc1.JANUARY, 1, 0, 0, 0); 291 gc1.set(gc1.HOUR_OF_DAY, hour); 292 if (!gc1.checkDate(1582, gc1.OCTOBER, 4)) { 293 errln("test case 1: " + gc1.getMessage()); 294 } 295 gc1.clear(); 296 gc1.set(1, gc1.JANUARY, 1, 0, 0, 0); 297 gc1.set(gc1.HOUR_OF_DAY, hour + 24); 298 if (!gc1.checkDate(1582, gc1.OCTOBER, 15)) { 299 errln("test case 2: " + gc1.getMessage()); 300 } 301 } 302 303 /** 304 * 6549953 (cal) WEEK_OF_YEAR and DAY_OF_YEAR calculation problems around Gregorian cutover 305 */ 306 public void Test6549953() { 307 Koyomi cal = new Koyomi(); 308 309 cal.set(YEAR, 1582); 310 cal.set(WEEK_OF_YEAR, 42); 311 cal.set(DAY_OF_WEEK, FRIDAY); 312 cal.checkFieldValue(WEEK_OF_YEAR, 42); 313 cal.checkFieldValue(DAY_OF_WEEK, FRIDAY); 314 if (!cal.checkDate(1582, OCTOBER, 29)) { 315 errln(cal.getMessage()); 316 } 317 cal.clear(); 318 cal.set(1582, OCTOBER, 1); 319 cal.set(DAY_OF_YEAR, 292); 320 if (!cal.checkDate(1582, OCTOBER, 29)) { 321 errln(cal.getMessage()); 322 } 323 } 324 }