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 4958050 27 * @summary Make sure that add() and roll() handle time zone offset changes (both raw and DST) correctly. 28 */ 29 30 import java.util.Locale; 31 import java.util.TimeZone; 32 import static java.util.Calendar.*; 33 34 public class Bug4958050 { 35 static int errorCount = 0; 36 37 public static void main(String[] args) { 38 // All the test cases depend on historical GMT offset changes 39 // of Asia/Novosibirsk. 40 Koyomi cal = new Koyomi(TimeZone.getTimeZone("Asia/Novosibirsk"), Locale.US); 41 System.out.println("Time zone = " + cal.getTimeZone().getID()); 42 43 // Test the week fields 44 int[] weekFields = { WEEK_OF_YEAR, WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH }; 45 for (int i = 0; i < weekFields.length; i++) { 46 int field = weekFields[i]; 47 // add() 48 cal.clear(); 49 cal.set(1919, DECEMBER, 14-7, 23, 50, 00); 50 cal.add(weekFields[i], +1); 51 if (!cal.checkDate(1919, DECEMBER, 14)) { 52 error("1919/12/07: add("+cal.getFieldName(weekFields[i])+", +1)\n" 53 + cal.getMessage()+" " + cal.toDateTimeString()); 54 } 55 cal.clear(); 56 cal.set(1930, JUNE, 21-7); 57 cal.add(weekFields[i], +1); 58 if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) { 59 error("1930/6/14: add("+cal.getFieldName(weekFields[i])+", +1)\n" 60 + cal.getMessage()+" " + cal.toDateTimeString()); 61 } 62 63 // roll() 64 cal.clear(); 65 cal.set(1919, DECEMBER, 14-7, 23, 50, 00); 66 cal.roll(weekFields[i], +1); 67 if (!cal.checkDate(1919, DECEMBER, 14)) { 68 error("1919/12/07: roll("+cal.getFieldName(weekFields[i])+", +1)\n" 69 + cal.getMessage()+" " + cal.toDateTimeString()); 70 } 71 cal.clear(); 72 cal.set(1930, JUNE, 21-7); 73 cal.roll(weekFields[i], +1); 74 if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) { 75 error("1930/6/14: roll("+cal.getFieldName(weekFields[i])+", +1)\n" 76 + cal.getMessage()+" " + cal.toDateTimeString()); 77 } 78 } 79 80 // Test the day fields 81 int[] dayFields = { DAY_OF_MONTH, DAY_OF_YEAR, DAY_OF_WEEK }; 82 for (int i = 0; i < dayFields.length; i++) { 83 int field = dayFields[i]; 84 // add() 85 cal.clear(); 86 cal.set(1919, DECEMBER, 14-1, 23, 50, 00); 87 cal.add(field, +1); 88 if (!cal.checkDate(1919, DECEMBER, 14)) { 89 error("1919/12/13: add("+cal.getFieldName(field)+", +1)\n" 90 + cal.getMessage()+" " + cal.toDateTimeString()); 91 } 92 cal.clear(); 93 cal.set(1919, DECEMBER, 14, 00, 00, 00); 94 cal.add(field, -1); 95 if (!cal.checkDate(1919, DECEMBER, 13)) { 96 error("1919/12/14: add("+cal.getFieldName(field)+", -1)\n" 97 + cal.getMessage()+" " + cal.toDateTimeString()); 98 } 99 cal.clear(); 100 cal.set(1930, JUNE, 21-1); 101 cal.add(field, +1); 102 if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) { 103 error("1930/6/20: add("+cal.getFieldName(field)+", +1)\n" 104 + cal.getMessage() + cal.toDateTimeString()); 105 } 106 cal.clear(); 107 cal.set(1930, JUNE, 21, 01, 00, 00); 108 cal.add(field, -1); 109 if (!cal.checkDateTime(1930, JUNE, 20, 01, 00, 00, 000)) { 110 error("1930/6/21: add("+cal.getFieldName(field)+", -1)\n" 111 + cal.getMessage()+" " + cal.toDateTimeString()); 112 } 113 114 // roll() 115 cal.clear(); 116 cal.set(1930, JUNE, 21-1); 117 int amount = +1; 118 if (field == DAY_OF_WEEK) { 119 amount += 700; 120 } 121 cal.roll(field, amount); 122 if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) { 123 error("1930/6/20: roll("+cal.getFieldName(field)+", +"+amount+")\n" 124 + cal.getMessage() + " " + cal.toDateTimeString()); 125 } 126 cal.clear(); 127 cal.set(1930, JUNE, 21, 01, 00, 00); 128 amount = -1; 129 if (field == DAY_OF_WEEK) { 130 amount -= 700; 131 } 132 cal.roll(field, amount); 133 if (!cal.checkDateTime(1930, JUNE, 20, 01, 00, 00, 000)) { 134 error("1930/6/21: roll("+cal.getFieldName(field)+", "+amount+")\n" 135 + cal.getMessage()+" "+cal.toDateTimeString()); 136 } 137 } 138 139 // Test the AM_PM field 140 // add() 141 cal.clear(); 142 cal.set(1919, DECEMBER, 14-1, 23, 50, 00); 143 cal.add(AM_PM, +1); 144 if (!cal.checkDate(1919, DECEMBER, 14) 145 || !cal.checkFieldValue(AM_PM, AM)) { 146 error("1919/12/13: add(AM_PM, +1)\n" 147 + cal.getMessage()+" "+cal.toDateTimeString()); 148 } 149 150 cal.clear(); 151 cal.set(1930, JUNE, 21-1, 12, 00, 00); 152 cal.add(AM_PM, +1); 153 if (!cal.checkDate(1930, JUNE, 21) 154 || !cal.checkFieldValue(AM_PM, AM)) { 155 error("1930/6/20: add(AM_PM, +1)\n" 156 + cal.getMessage()+" "+cal.toDateTimeString()); 157 } 158 159 cal.clear(); 160 cal.set(1930, JUNE, 21-2, 12, 00, 00); 161 cal.add(AM_PM, +3); 162 if (!cal.checkDate(1930, JUNE, 21) 163 || !cal.checkFieldValue(AM_PM, AM)) { 164 error("1930/6/10: add(AM_PM, +3)\n" 165 + cal.getMessage()+" "+cal.toDateTimeString()); 166 } 167 168 cal.clear(); 169 cal.set(1919, DECEMBER, 14, 11, 50, 00); 170 cal.add(AM_PM, -1); 171 if (!cal.checkDateTime(1919, DECEMBER, 14-1, 23, 50, 00, 000) 172 || !cal.checkFieldValue(AM_PM, PM)) { 173 error("1919/12/14 11:50:00: add(AM_PM, -1)\n" 174 + cal.getMessage()+" "+cal.toDateTimeString()); 175 } 176 177 cal.clear(); 178 cal.set(1930, JUNE, 21, 01, 00, 00); 179 cal.add(AM_PM, -1); 180 if (!cal.checkDateTime(1930, JUNE, 21-1, 01+12, 00, 00, 000) 181 || !cal.checkFieldValue(AM_PM, PM)) { 182 error("1930/6/20: add(AM_PM, -1)\n" 183 + cal.getMessage()+" "+cal.toDateTimeString()); 184 } 185 186 cal.clear(); 187 cal.set(1930, JUNE, 21, 01, 00, 00); 188 cal.add(AM_PM, -3); 189 if (!cal.checkDateTime(1930, JUNE, 21-2, 01+12, 00, 00, 000) 190 || !cal.checkFieldValue(AM_PM, PM)) { 191 error("1930/6/10: add(AM_PM, -3)\n" 192 + cal.getMessage()+" "+cal.toDateTimeString()); 193 } 194 195 // roll() (should NOT change the date) 196 cal.clear(); 197 cal.set(1919, DECEMBER, 14-1, 23, 50, 00); 198 cal.roll(AM_PM, +1); 199 if (!cal.checkDateTime(1919, DECEMBER, 14-1, 23-12, 50, 00, 000) 200 || !cal.checkFieldValue(AM_PM, AM)) { 201 error("1919/12/13: roll(AM_PM, +1)\n" 202 + cal.getMessage()+" "+cal.toDateTimeString()); 203 } 204 205 cal.clear(); 206 cal.set(1930, JUNE, 21-1, 12, 00, 00); 207 cal.roll(AM_PM, +1); 208 if (!cal.checkDateTime(1930, JUNE, 21-1, 12-12, 00, 00, 000) 209 || !cal.checkFieldValue(AM_PM, AM)) { 210 error("1930/6/20: roll(AM_PM, +1)\n" 211 + cal.getMessage()+" "+cal.toDateTimeString()); 212 } 213 214 cal.clear(); 215 cal.set(1930, JUNE, 21-2, 12, 00, 00); 216 cal.roll(AM_PM, +3); 217 if (!cal.checkDateTime(1930, JUNE, 21-2, 12-12, 00, 00, 000) 218 || !cal.checkFieldValue(AM_PM, AM)) { 219 error("1930/6/10: roll(AM_PM, +3)\n" 220 + cal.getMessage()+" "+cal.toDateTimeString()); 221 } 222 223 // Test the HOUR_OF_DAY field 224 // add() 225 cal.clear(); 226 cal.set(1930, JUNE, 20, 23, 00, 00); 227 cal.add(HOUR_OF_DAY, +1); 228 if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) { 229 error("1930/6/20 23:00:00: add(HOUR_OF_DAY, +1)\n" 230 + cal.getMessage()+" "+cal.toDateTimeString()); 231 } 232 233 // roll() (should NOT change the date) 234 cal.clear(); 235 cal.set(1930, JUNE, 20, 23, 00, 00); 236 cal.roll(HOUR_OF_DAY, +1); 237 if (!cal.checkDateTime(1930, JUNE, 20, 00, 00, 00, 000)) { 238 error("1930/6/20 23:00:00: roll(HOUR_OF_DAY, +1)\n" 239 + cal.getMessage()+" "+cal.toDateTimeString()); 240 } 241 242 checkErrors(); 243 } 244 245 static void error(String s) { 246 System.out.println(s); 247 errorCount++; 248 } 249 250 static void checkErrors() { 251 if (errorCount > 0) { 252 throw new RuntimeException("Failed: " + errorCount + " error(s)"); 253 } 254 } 255 }