1 /* 2 * Copyright (c) 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 8152077 27 * @summary Make sure that roll() with HOUR/HOUR_OF_DAY works around standard/daylight 28 * time transitions 29 */ 30 31 import java.util.Calendar; 32 import java.util.GregorianCalendar; 33 import java.util.TimeZone; 34 import static java.util.Calendar.*; 35 36 public class Bug8152077 { 37 private static final TimeZone LA = TimeZone.getTimeZone("America/Los_Angeles"); 38 private static final TimeZone BR = TimeZone.getTimeZone("America/Sao_Paulo"); 39 40 private static final int[] ALLDAY_HOURS = { 41 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 42 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 43 }; 44 private static final int[] AM_HOURS = { 45 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 46 }; 47 private static final int[] PM_HOURS = { // in 24-hour clock 48 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 49 }; 50 51 private static int errors; 52 53 public static void main(String[] args) { 54 TimeZone initialTz = TimeZone.getDefault(); 55 try { 56 testRoll(LA, new int[] { 2016, MARCH, 13 }, 57 new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 58 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }); 59 testRoll(LA, new int[] { 2016, MARCH, 13 }, 60 new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); 61 testRoll(LA, new int[] { 2016, MARCH, 13 }, PM_HOURS); 62 63 testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, ALLDAY_HOURS); 64 testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, AM_HOURS); 65 testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, PM_HOURS); 66 67 testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, ALLDAY_HOURS); 68 testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, AM_HOURS); 69 testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, PM_HOURS); 70 71 testRoll(BR, new int[] { 2016, OCTOBER, 15 }, ALLDAY_HOURS); 72 testRoll(BR, new int[] { 2016, OCTOBER, 15 }, PM_HOURS); 73 testRoll(BR, new int[] { 2016, OCTOBER, 16 }, 74 new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 75 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }); 76 testRoll(BR, new int[] { 2016, OCTOBER, 16 }, 77 new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); 78 testRoll(BR, new int[] { 2016, OCTOBER, 16 }, PM_HOURS); 79 } finally { 80 TimeZone.setDefault(initialTz); 81 } 82 if (errors > 0) { 83 throw new RuntimeException("Test failed"); 84 } 85 } 86 87 private static void testRoll(TimeZone tz, int[] params, int[] sequence) { 88 TimeZone.setDefault(tz); 89 for (int i = 0; i < sequence.length; i++) { 90 testRoll(+1, params, sequence, i); 91 testRoll(-1, params, sequence, i); 92 } 93 } 94 95 // amount must be 1 or -1. 96 private static void testRoll(int amount, int[] params, int[] sequence, int startIndex) { 97 int year = params[0]; 98 int month = params[1]; 99 int dayOfMonth = params[2]; 100 int hourOfDay = sequence[startIndex]; 101 Calendar cal = new GregorianCalendar(year, month, dayOfMonth, 102 hourOfDay, 0, 0); 103 int ampm = cal.get(AM_PM); 104 105 int length = sequence.length; 106 int count = length * 2; 107 int field = (length > 12) ? HOUR_OF_DAY : HOUR; 108 109 System.out.printf("roll(%s, %2d) starting from %s%n", 110 (field == HOUR) ? "HOUR" : "HOUR_OF_DAY", amount, cal.getTime()); 111 for (int i = 0; i < count; i++) { 112 int index = (amount > 0) ? (startIndex + i + 1) % length 113 : Math.floorMod(startIndex - i - 1, length); 114 int expected = sequence[index]; 115 if (field == HOUR) { 116 expected %= 12; 117 } 118 cal.roll(field, amount); 119 int value = cal.get(field); 120 if (value != expected) { 121 System.out.println("Unexpected field value: got=" + value 122 + ", expected=" + expected); 123 errors++; 124 } 125 if (cal.get(DAY_OF_MONTH) != dayOfMonth) { 126 System.out.println("DAY_OF_MONTH changed: " + dayOfMonth 127 + " to " + cal.get(DAY_OF_MONTH)); 128 } 129 if (field == HOUR && cal.get(AM_PM) != ampm) { 130 System.out.println("AM_PM changed: " + ampm + " to " + cal.get(AM_PM)); 131 errors++; 132 } 133 } 134 } 135 }