1 /*
  2  * Copyright (c) 2001, 2024, 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 4322313
 27  * @summary Make sure that new implementation of custom time zone
 28  * support for TimeZone.getTimeZone() works correctly and the
 29  * getDisplayName() methods are locale independent.
 30  * @run junit Bug4322313
 31  */
 32 
 33 import java.util.Locale;
 34 import java.util.TimeZone;
 35 
 36 import org.junit.jupiter.api.Test;
 37 
 38 import static org.junit.jupiter.api.Assertions.fail;
 39 
 40 public class Bug4322313 {
 41     private static final int MPM = 60 * 1000;    /* Milliseconds per minute */
 42     private static final Object[][] VALIDS = {
 43         /* given ID    rawOffset   normalized ID */
 44         {"GMT+00:00",  0,          "GMT+00:00"},
 45         {"GMT+3:04",   184 * MPM,  "GMT+03:04"},
 46         {"GMT+03:04",  184 * MPM,  "GMT+03:04"},
 47         {"GMT+13:42",  822 * MPM,  "GMT+13:42"},
 48         /* ISO-LATIN-1 digits */
 49         {"GMT+\u0030\u0031:\u0032\u0033", 83 * MPM, "GMT+01:23"},
 50 
 51         {"GMT+0",      0,          "GMT+00:00"},
 52         {"GMT+3",      180 * MPM,  "GMT+03:00"},
 53         {"GMT+13",     780 * MPM,  "GMT+13:00"},
 54         {"GMT+034",    34 * MPM,   "GMT+00:34"},
 55         {"GMT+1034",   634 * MPM,  "GMT+10:34"},
 56 
 57         {"GMT-00:00",  0,          "GMT-00:00"},
 58         {"GMT-3:04",   -184 * MPM, "GMT-03:04"},
 59         {"GMT-03:04",  -184 * MPM, "GMT-03:04"},
 60         {"GMT-13:42",  -822 * MPM, "GMT-13:42"},
 61         /* ISO-LATIN-1 digits */
 62         {"GMT-\u0030\u0031:\u0032\u0033", -83 * MPM, "GMT-01:23"},
 63 
 64         {"GMT-0",      0,          "GMT-00:00"},
 65         {"GMT-3",      -180 * MPM, "GMT-03:00"},
 66         {"GMT-13",     -780 * MPM, "GMT-13:00"},
 67         {"GMT-034",    -34 * MPM,  "GMT-00:34"},
 68         {"GMT-1034",   -634 * MPM, "GMT-10:34"},
 69     };
 70 
 71     private static final String[] INVALIDS = {
 72         "GMT+5:8",    "GMT+11:1",    "GMT+23:60",  "GMT+24:13",
 73         "GMT+0a:0A",  "GMT +13:42",  "GMT+ 13:42", "GMT+13 :42",
 74         "GMT+13: 42", "GMT+421:950", "GMT+-13:42", "GMT+!13:42",
 75         "GMT+a",      "GMT+24",      "GMT+060",    "GMT+3003",
 76         "GMT+42195",  "GMT+-1",      "GMT+-15",    " GMT",
 77 
 78         "GMT-5:8",    "GMT-11:1",    "GMT-23:60",  "GMT-24:13",
 79         "GMT-0a:0A",  "GMT -13:42",  "GMT- 13:42", "GMT-13 :42",
 80         "GMT-13: 42", "GMT-421:950", "GMT-+13:42", "GMT-#13:42",
 81         "GMT-a",      "GMT-24",      "GMT-060",    "GMT-2403",
 82         "GMT-42195",  "GMT-+1",      "GMT-+15",    "G M T",
 83         "GMT+09:00 ",
 84     };
 85 
 86     @Test
 87     void Test4322313() {
 88         Locale savedLocale = Locale.getDefault();
 89         TimeZone savedTimeZone = TimeZone.getDefault();
 90         boolean err = false;
 91 
 92         Locale[] locs = Locale.getAvailableLocales();
 93         try {
 94             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
 95 
 96             for (int i = 0; i < locs.length; i++) {
 97                 Locale locale = locs[i];
 98                 Locale.setDefault(locale);
 99 
100 
101                 /* Okay case */
102                 for (int k = 0; k < VALIDS.length; k++) {
103                     TimeZone tz = TimeZone.getTimeZone((String)VALIDS[k][0]);
104                     int offset;
105 
106                     if (!tz.getID().equals(VALIDS[k][2])) {
107                         err = true;
108                         System.err.println("\tFailed [Locale=" +
109                                            locale + ", \"" + VALIDS[k][0] +
110                                            "\"] Invalid TimeZone ID, expected:" +
111                                            VALIDS[k][2] + ", got:" + tz.getID() + ", " + tz);
112                     } else {
113                         System.out.println("\tPassed [Locale=" +
114                               locale + ", \"" + VALIDS[k][0] +
115                               "\"] Valid TimeZone ID, got:" + VALIDS[k][2]);
116                     }
117 
118                     offset = tz.getRawOffset();
119                     if (offset != (int)VALIDS[k][1]) {
120                         err = true;
121                         System.err.println("\tFailed [Locale=" +
122                                            locale + ", \"" + VALIDS[k][0] +
123                                            "\"] Invalid RawOffset, expected:" + VALIDS[k][1] +
124                                            ", got:" + offset + ", " + tz);
125                     } else {
126                         System.out.println("\tPassed [Locale=" +
127                               locale + ", \"" + VALIDS[k][0] +
128                               "\"] Vaild RawOffset, got:" + offset);
129                     }
130 
131                     offset = tz.getDSTSavings();
132                     if (offset != 0) {
133                         err = true;
134                         System.err.println("\tFailed [Locale=" +
135                                            locale + ", \"" + VALIDS[k][0] +
136                                            "\"] DSTSavings should be zero, got:" + offset +
137                                            ", " + tz);
138                     } else {
139                         System.out.println("\tPassed [Locale=" +
140                               locale + ", \"" + VALIDS[k][0] +
141                               "\"] DSTSavings is zero.");
142                     }
143                 }
144 
145                 /* Error case */
146                 for (int k=0; k < INVALIDS.length; k++) {
147                     TimeZone tz = TimeZone.getTimeZone(INVALIDS[k]);
148                     int offset;
149 
150                     if (!tz.getID().equals("GMT")) {
151                         err = true;
152                         System.err.println("\tFailed [Locale=" +
153                                            locale + ", \"" + INVALIDS[k] +
154                                            "\"] Invalid TimeZone ID, expected:GMT, got:" +
155                                            tz.getID() + ", " + tz);
156                     } else {
157                         System.out.println("\tPassed [Locale=" +
158                               locale + ", \"" + INVALIDS[k] +
159                               "\"] Valid TimeZone ID, got:" + tz.getID());
160                     }
161 
162                     offset = tz.getRawOffset();
163                     if (offset != 0) {
164                         err = true;
165                         System.err.println("\tFailed [Locale=" +
166                                            locale + ", \"" + INVALIDS[k] +
167                                            "\"] RawOffset should be zero, got:" + offset +
168                                            ", " + tz);
169                     } else {
170                         System.out.println("\tPassed [Locale=" +
171                               locale + ", \"" + INVALIDS[k] +
172                               "\"] RawOffset is zero.");
173                     }
174 
175                     offset = tz.getDSTSavings();
176                     if (offset != 0) {
177                         err = true;
178                         System.err.println("\tFailed [Locale=" +
179                                            locale + ", \"" + INVALIDS[k] +
180                                            "\"] DSTSavings should be zero, got:" + offset +
181                                            ", " + tz);
182                     } else {
183                         System.out.println("\tPassed [Locale=" +
184                               locale + ", \"" + INVALIDS[k] +
185                               "\"] DSTSavings is zero.");
186                     }
187                 }
188 
189                 // getDisplayName() tests
190                 {
191                     String normalizedID = "GMT-08:00";
192                     TimeZone tz = TimeZone.getTimeZone("GMT-8");
193                     String s;
194                     s = tz.getDisplayName(true, tz.LONG);
195                     if (!normalizedID.equals(s)) {
196                         err = true;
197                         System.err.println("getDisplayName returned unexpected name: " + s +
198                                            " in " + locale);
199                     }
200                     s = tz.getDisplayName(true, tz.SHORT);
201                     if (!normalizedID.equals(s)) {
202                         err = true;
203                         System.err.println("getDisplayName returned unexpected name: " + s +
204                                            " in " + locale);
205                     }
206                     s = tz.getDisplayName(false, tz.LONG);
207                     if (!normalizedID.equals(s)) {
208                         err = true;
209                         System.err.println("getDisplayName returned unexpected name: " + s +
210                                            " in " + locale);
211                     }
212                     s = tz.getDisplayName(false, tz.SHORT);
213                     if (!normalizedID.equals(s)) {
214                         err = true;
215                         System.err.println("getDisplayName returned unexpected name: " + s +
216                                            " in " + locale);
217                     }
218                 }
219             }
220         } finally {
221             Locale.setDefault(savedLocale);
222             TimeZone.setDefault(savedTimeZone);
223         }
224         if (err) {
225             fail("TimeZone.getTimeZone() test failed");
226         } else {
227             System.out.println("TimeZone.getTimeZone() test passed");
228         }
229     }
230 }