1 /* 2 * Copyright (c) 1998, 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 * @summary test International Date Format 27 * @bug 8008577 28 * @library /java/text/testlib 29 * @run main/othervm -Djava.locale.providers=COMPAT,SPI IntlTestDateFormat 30 * @key randomness 31 */ 32 /* 33 (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 34 (C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved 35 36 The original version of this source code and documentation is copyrighted and 37 owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are 38 provided under terms of a License Agreement between Taligent and Sun. This 39 technology is protected by multiple US and International patents. This notice and 40 attribution to Taligent may not be removed. 41 Taligent is a registered trademark of Taligent, Inc. 42 */ 43 44 import java.text.*; 45 import java.util.*; 46 47 public class IntlTestDateFormat extends IntlTest { 48 // Values in milliseconds (== Date) 49 private static final long ONESECOND = 1000; 50 private static final long ONEMINUTE = 60 * ONESECOND; 51 private static final long ONEHOUR = 60 * ONEMINUTE; 52 private static final long ONEDAY = 24 * ONEHOUR; 53 private static final double ONEYEAR = 365.25 * ONEDAY; // Approximate 54 55 // EModes 56 private static final byte GENERIC = 0; 57 private static final byte TIME = GENERIC + 1; 58 private static final byte DATE = TIME + 1; 59 private static final byte DATE_TIME = DATE + 1; 60 61 private DateFormat fFormat = DateFormat.getInstance(); 62 private String fTestName = new String("getInstance"); 63 private int fLimit = 3; // How many iterations it should take to reach convergence 64 main(String[] args)65 public static void main(String[] args) throws Exception { 66 new IntlTestDateFormat().run(args); 67 } 68 TestLocale()69 public void TestLocale() { 70 localeTest(Locale.getDefault(), "Default Locale"); 71 } 72 73 // This test does round-trip testing (format -> parse -> format -> parse -> etc.) of DateFormat. localeTest(final Locale locale, final String localeName)74 public void localeTest(final Locale locale, final String localeName) { 75 int timeStyle, dateStyle; 76 77 // For patterns including only time information and a timezone, it may take 78 // up to three iterations, since the timezone may shift as the year number 79 // is determined. For other patterns, 2 iterations should suffice. 80 fLimit = 3; 81 82 for(timeStyle = 0; timeStyle < 4; timeStyle++) { 83 fTestName = new String("Time test " + timeStyle + " (" + localeName + ")"); 84 try { 85 fFormat = DateFormat.getTimeInstance(timeStyle, locale); 86 } 87 catch(StringIndexOutOfBoundsException e) { 88 errln("FAIL: localeTest time getTimeInstance exception"); 89 throw e; 90 } 91 TestFormat(); 92 } 93 94 fLimit = 2; 95 96 for(dateStyle = 0; dateStyle < 4; dateStyle++) { 97 fTestName = new String("Date test " + dateStyle + " (" + localeName + ")"); 98 try { 99 fFormat = DateFormat.getDateInstance(dateStyle, locale); 100 } 101 catch(StringIndexOutOfBoundsException e) { 102 errln("FAIL: localeTest date getTimeInstance exception"); 103 throw e; 104 } 105 TestFormat(); 106 } 107 108 for(dateStyle = 0; dateStyle < 4; dateStyle++) { 109 for(timeStyle = 0; timeStyle < 4; timeStyle++) { 110 fTestName = new String("DateTime test " + dateStyle + "/" + timeStyle + " (" + localeName + ")"); 111 try { 112 fFormat = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); 113 } 114 catch(StringIndexOutOfBoundsException e) { 115 errln("FAIL: localeTest date/time getDateTimeInstance exception"); 116 throw e; 117 } 118 TestFormat(); 119 } 120 } 121 } 122 TestFormat()123 public void TestFormat() { 124 if (fFormat == null) { 125 errln("FAIL: DateFormat creation failed"); 126 return; 127 } 128 // logln("TestFormat: " + fTestName); 129 Date now = new Date(); 130 tryDate(new Date(0)); 131 tryDate(new Date((long) 1278161801778.0)); 132 tryDate(now); 133 // Shift 6 months into the future, AT THE SAME TIME OF DAY. 134 // This will test the DST handling. 135 tryDate(new Date(now.getTime() + 6*30*ONEDAY)); 136 137 Date limit = new Date(now.getTime() * 10); // Arbitrary limit 138 for (int i=0; i<2; ++i) 139 // tryDate(new Date(floor(randDouble() * limit))); 140 tryDate(new Date((long) (randDouble() * limit.getTime()))); 141 } 142 describeTest()143 private void describeTest() { 144 if (fFormat == null) { 145 errln("FAIL: no DateFormat"); 146 return; 147 } 148 149 // Assume it's a SimpleDateFormat and get some info 150 SimpleDateFormat s = (SimpleDateFormat) fFormat; 151 logln(fTestName + " Pattern " + s.toPattern()); 152 } 153 tryDate(Date theDate)154 private void tryDate(Date theDate) { 155 final int DEPTH = 10; 156 Date[] date = new Date[DEPTH]; 157 StringBuffer[] string = new StringBuffer[DEPTH]; 158 159 int dateMatch = 0; 160 int stringMatch = 0; 161 boolean dump = false; 162 int i; 163 for (i=0; i<DEPTH; ++i) string[i] = new StringBuffer(); 164 for (i=0; i<DEPTH; ++i) { 165 if (i == 0) date[i] = theDate; 166 else { 167 try { 168 date[i] = fFormat.parse(string[i-1].toString()); 169 } 170 catch (ParseException e) { 171 describeTest(); 172 errln("********** FAIL: Parse of " + string[i-1] + " failed."); 173 dump = true; 174 break; 175 } 176 } 177 FieldPosition position = new FieldPosition(0); 178 fFormat.format(date[i], string[i], position); 179 if (i > 0) { 180 if (dateMatch == 0 && date[i] == date[i-1]) dateMatch = i; 181 else if (dateMatch > 0 && date[i] != date[i-1]) { 182 describeTest(); 183 errln("********** FAIL: Date mismatch after match."); 184 dump = true; 185 break; 186 } 187 if (stringMatch == 0 && string[i] == string[i-1]) stringMatch = i; 188 else if (stringMatch > 0 && string[i] != string[i-1]) { 189 describeTest(); 190 errln("********** FAIL: String mismatch after match."); 191 dump = true; 192 break; 193 } 194 } 195 if (dateMatch > 0 && stringMatch > 0) break; 196 } 197 if (i == DEPTH) --i; 198 199 if (stringMatch > fLimit || dateMatch > fLimit) { 200 describeTest(); 201 errln("********** FAIL: No string and/or date match within " + fLimit + " iterations."); 202 dump = true; 203 } 204 205 if (dump) { 206 for (int k=0; k<=i; ++k) { 207 logln("" + k + ": " + date[k] + " F> " + string[k] + " P> "); 208 } 209 } 210 } 211 212 // Return a random double from 0.01 to 1, inclusive randDouble()213 private double randDouble() { 214 // Assume 8-bit (or larger) rand values. Also assume 215 // that the system rand() function is very poor, which it always is. 216 // double d; 217 // int i; 218 // do { 219 // for (i=0; i < sizeof(double); ++i) 220 // { 221 // char poke = (char*)&d; 222 // poke[i] = (rand() & 0xFF); 223 // } 224 // } while (TPlatformUtilities.isNaN(d) || TPlatformUtilities.isInfinite(d)); 225 226 // if (d < 0.0) d = -d; 227 // if (d > 0.0) 228 // { 229 // double e = floor(log10(d)); 230 // if (e < -2.0) d *= pow(10.0, -e-2); 231 // else if (e > -1.0) d /= pow(10.0, e+1); 232 // } 233 // return d; 234 Random rand = new Random(); 235 return rand.nextDouble(); 236 } 237 TestAvailableLocales()238 public void TestAvailableLocales() { 239 final Locale[] locales = DateFormat.getAvailableLocales(); 240 long count = locales.length; 241 logln("" + count + " available locales"); 242 if (locales != null && count != 0) { 243 StringBuffer all = new StringBuffer(); 244 for (int i=0; i<count; ++i) { 245 if (i!=0) all.append(", "); 246 all.append(locales[i].getDisplayName()); 247 } 248 logln(all.toString()); 249 } 250 else errln("********** FAIL: Zero available locales or null array pointer"); 251 } 252 253 /* This test is too slow; we disable it for now 254 public void TestMonster() { 255 final Locale[] locales = DateFormat.getAvailableLocales(); 256 long count = locales.length; 257 if (locales != null && count != 0) { 258 for (int i=0; i<count; ++i) { 259 String name = locales[i].getDisplayName(); 260 logln("Testing " + name + "..."); 261 try { 262 localeTest(locales[i], name); 263 } 264 catch(Exception e) { 265 errln("FAIL: TestMonster localeTest exception" + e); 266 } 267 } 268 } 269 } 270 */ 271 } 272 273 //eof 274