1 /* 2 * Copyright (c) 1997, 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 4052223 4089987 4469904 4326988 4486735 8008577 8045998 8140571 27 * @summary test DateFormat and SimpleDateFormat. 28 * @library /java/text/testlib 29 * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatTest 30 */ 31 32 import java.util.*; 33 import java.text.*; 34 import static java.util.GregorianCalendar.*; 35 36 public class DateFormatTest extends IntlTest 37 { 38 public static void main(String[] args) throws Exception { 39 Locale reservedLocale = Locale.getDefault(); 40 try { 41 Locale.setDefault(Locale.US); 42 new DateFormatTest().run(args); 43 } finally { 44 // restore the reserved locale 45 Locale.setDefault(reservedLocale); 46 } 47 } 48 49 // Test 4 digit year parsing with pattern "yy" 50 @SuppressWarnings("deprecation") 51 public void TestYearParsing() 52 { 53 String str = "7/Sep/2001"; 54 Date exp = new Date(2001-1900, SEPTEMBER, 7); 55 String pat = "d/MMM/yy"; 56 SimpleDateFormat sdf = new SimpleDateFormat(pat, Locale.US); 57 try { 58 Date d = sdf.parse(str); 59 logln(str + " parses with " + pat + " to " + d); 60 if (d.getTime() != exp.getTime()) { 61 errln("FAIL: Expected " + exp); 62 } 63 } 64 catch (ParseException e) { 65 errln(str + " parse fails with " + pat); 66 } 67 } 68 69 // Test written by Wally Wedel and emailed to me. 70 public void TestWallyWedel() 71 { 72 /* 73 * Instantiate a TimeZone so we can get the ids. 74 */ 75 TimeZone tz = new SimpleTimeZone(7,""); 76 /* 77 * Computational variables. 78 */ 79 int offset, hours, minutes; 80 /* 81 * Instantiate a SimpleDateFormat set up to produce a full time 82 zone name. 83 */ 84 SimpleDateFormat sdf = new SimpleDateFormat("zzzz"); 85 /* 86 * A String array for the time zone ids. 87 */ 88 String[] ids = TimeZone.getAvailableIDs(); 89 /* 90 * How many ids do we have? 91 */ 92 logln("Time Zone IDs size: " + ids.length); 93 /* 94 * Column headings (sort of) 95 */ 96 logln("Ordinal ID offset(h:m) name"); 97 /* 98 * Loop through the tzs. 99 */ 100 Date today = new Date(); 101 Calendar cal = Calendar.getInstance(); 102 for (int i = 0; i < ids.length; i++) { 103 // logln(i + " " + ids[i]); 104 TimeZone ttz = TimeZone.getTimeZone(ids[i]); 105 // offset = ttz.getRawOffset(); 106 cal.setTimeZone(ttz); 107 cal.setTime(today); 108 offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET); 109 // logln(i + " " + ids[i] + " offset " + offset); 110 char sign = '+'; 111 if (offset < 0) { sign = '-'; offset = -offset; } 112 hours = offset/3600000; 113 minutes = (offset%3600000)/60000; 114 String dstOffset = "" + sign + (hours < 10 ? "0" : "") + 115 hours + ':' + (minutes < 10 ? "0" : "") + minutes; 116 /* 117 * Instantiate a date so we can display the time zone name. 118 */ 119 sdf.setTimeZone(ttz); 120 /* 121 * Format the output. 122 */ 123 StringBuffer tzS = new StringBuffer(); 124 sdf.format(today,tzS, new FieldPosition(0)); 125 String fmtOffset = tzS.toString(); 126 String fmtDstOffset = null; 127 if (fmtOffset.startsWith("GMT")) 128 { 129 fmtDstOffset = fmtOffset.substring(3); 130 } 131 /* 132 * Show our result. 133 */ 134 boolean ok = fmtDstOffset == null || fmtDstOffset.equals(dstOffset); 135 if (ok) 136 { 137 logln(i + " " + ids[i] + " " + dstOffset + 138 " " + fmtOffset + 139 (fmtDstOffset != null ? " ok" : " ?")); 140 } 141 else 142 { 143 errln(i + " " + ids[i] + " " + dstOffset + 144 " " + fmtOffset + " *** FAIL ***"); 145 } 146 } 147 } 148 149 // Test equals 150 public void TestEquals() 151 { 152 DateFormat fmtA = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); 153 154 DateFormat fmtB = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); 155 156 if (!fmtA.equals(fmtB)) { 157 errln("FAIL"); 158 } 159 } 160 161 // Check out some specific parsing problem 162 @SuppressWarnings("deprecation") 163 public void TestTwoDigitYearDSTParse() 164 { 165 SimpleDateFormat fullFmt = 166 new SimpleDateFormat("EEE MMM dd HH:mm:ss.SSS zzz yyyy G"); 167 168 //DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL, 169 // Locale.ENGLISH); 170 SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yy h:mm:ss 'o''clock' a z", 171 Locale.ENGLISH); 172 //Date date = new Date(2004-1900, Calendar.APRIL, 3, 2, 20, 47); 173 //logln(fmt.format(date)); // This shows what the current locale format is 174 //logln(((SimpleDateFormat)fmt).toPattern()); 175 TimeZone save = TimeZone.getDefault(); 176 TimeZone PST = TimeZone.getTimeZone("PST"); 177 String s = "03-Apr-04 2:20:47 o'clock AM PST"; 178 int hour = 2; 179 try { 180 TimeZone.setDefault(PST); 181 Date d = fmt.parse(s); 182 logln(s + " P> " + fullFmt.format(d)); 183 if (d.getHours() != hour) { 184 errln("FAIL: Should parse to hour " + hour); 185 } 186 } 187 catch (ParseException e) { errln("FAIL: " + e.getMessage()); } 188 finally { 189 TimeZone.setDefault(save); 190 } 191 } 192 193 static String escape(String s) 194 { 195 StringBuilder buf = new StringBuilder(); 196 for (int i=0; i<s.length(); ++i) 197 { 198 char c = s.charAt(i); 199 if (c <= (char)0x7F) { 200 buf.append(c); 201 } else { 202 buf.append("\\u"); 203 buf.append(Integer.toHexString((c & 0xF000) >> 12)); 204 buf.append(Integer.toHexString((c & 0x0F00) >> 8)); 205 buf.append(Integer.toHexString((c & 0x00F0) >> 4)); 206 buf.append(Integer.toHexString(c & 0x000F)); 207 } 208 } 209 return buf.toString(); 210 } 211 212 // Test field position return values 213 static String fieldNames[] = { 214 "ERA_FIELD", "YEAR_FIELD", "MONTH_FIELD", 215 "WEEK_OF_YEAR_FIELD", "WEEK_OF_MONTH_FIELD", "DATE_FIELD", 216 "DAY_OF_YEAR_FIELD", "DAY_OF_WEEK_FIELD", "DAY_OF_WEEK_IN_MONTH_FIELD", 217 "AM_PM_FIELD", "HOUR0_FIELD", "HOUR1_FIELD", 218 "HOUR_OF_DAY0_FIELD", "HOUR_OF_DAY1_FIELD", 219 "MINUTE_FIELD", "SECOND_FIELD", 220 "MILLISECOND_FIELD", "TIMEZONE_FIELD", 221 }; 222 static int fieldIDs[] = { 223 DateFormat.ERA_FIELD, DateFormat.YEAR_FIELD, DateFormat.MONTH_FIELD, 224 DateFormat.WEEK_OF_YEAR_FIELD, DateFormat.WEEK_OF_MONTH_FIELD, DateFormat.DATE_FIELD, 225 DateFormat.DAY_OF_YEAR_FIELD, DateFormat.DAY_OF_WEEK_FIELD, DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD, 226 DateFormat.AM_PM_FIELD, DateFormat.HOUR0_FIELD, DateFormat.HOUR1_FIELD, 227 DateFormat.HOUR_OF_DAY0_FIELD, DateFormat.HOUR_OF_DAY1_FIELD, 228 DateFormat.MINUTE_FIELD, DateFormat.SECOND_FIELD, 229 DateFormat.MILLISECOND_FIELD, DateFormat.TIMEZONE_FIELD, 230 }; 231 232 /** 233 * Bug 4089987 234 */ 235 public void TestFieldPosition() 236 { 237 DateFormat[] dateFormats = { 238 DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL, 239 Locale.US), 240 241 DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL,Locale.FRANCE), 242 new SimpleDateFormat("G, y, M, d, k, H, m, s, S, E, D, F, w, W, a, h, K, z"), 243 new SimpleDateFormat("G, yy, M, d, k, H, m, s, S, E, D, F, w, W, a, h, K, z"), 244 new SimpleDateFormat( "GGGG, yyyy, MMMM, dddd, kkkk, HHHH, mmmm, ssss, " + 245 "SSSS, EEEE, DDDD, " + 246 "FFFF, wwww, WWWW, aaaa, hhhh, KKKK, zzzz") 247 }; 248 String[] expected = 249 { 250 "", "1997", "August", "", "", "13", "", "Wednesday", "", 251 "PM", "", "2", "", "", "34", "12", "", "PDT", 252 253 "", "1997", "ao\u00FBt", "", "", "13", "", "mercredi", "", "", 254 "", "", "14", "", "34", "", "", "PDT" /*"GMT-07:00"*/, 255 256 "AD", "1997", "8", "33", "3", "13", "225", "Wed", "2", "PM", 257 "2", "2", "14", "14", "34", "12", "513", "PDT", 258 259 "AD", "97", "8", "33", "3", "13", "225", "Wed", "2", "PM", 260 "2", "2", "14", "14", "34", "12", "513", "PDT", 261 262 "AD", "1997", "August", "0033", "0003", "0013", "0225", 263 "Wednesday", "0002", "PM", "0002", "0002", "0014", "0014", 264 "0034", "0012", "0513", "Pacific Daylight Time", 265 }; 266 Date someDate = new Date(871508052513L); 267 TimeZone PST = TimeZone.getTimeZone("PST"); 268 for (int j = 0, exp = 0; j < dateFormats.length; ++j) { 269 DateFormat df = dateFormats[j]; 270 if (!(df instanceof SimpleDateFormat)) { 271 continue; 272 } 273 df.setTimeZone(PST); 274 logln(" Pattern = " + ((SimpleDateFormat)df).toPattern()); 275 logln(" Result = " + df.format(someDate)); 276 for (int i = 0; i < fieldIDs.length; ++i) 277 { 278 String field = getFieldText(df, fieldIDs[i], someDate); 279 if (!field.equals(expected[exp])) { 280 errln("FAIL: field #" + i + " " + fieldNames[i] + " = \"" + 281 escape(field) + "\", expected \"" + escape(expected[exp]) + "\""); 282 } 283 ++exp; 284 } 285 } 286 } 287 // get the string value for the given field for the given date 288 static String getFieldText(DateFormat df, int field, Date date) 289 { 290 StringBuffer buffer = new StringBuffer(); 291 FieldPosition pos = new FieldPosition(field); 292 df.format(date, buffer, pos); 293 return buffer.toString().substring(pos.getBeginIndex(), 294 pos.getEndIndex()); 295 } 296 297 // Test parsing of partial strings 298 @SuppressWarnings("deprecation") 299 public void TestPartialParse994() 300 { 301 SimpleDateFormat f = new SimpleDateFormat(); 302 Calendar cal = new GregorianCalendar(2014 - 80, JANUARY, 1); 303 f.set2DigitYearStart(cal.getTime()); 304 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", new Date(97, 1-1, 17, 10, 11, 42)); 305 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null); 306 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null); 307 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null); 308 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null); 309 } 310 311 void tryPat994(SimpleDateFormat format, String pat, String str, Date expected) 312 { 313 logln("Pattern \"" + pat + "\" String \"" + str + "\""); 314 try { 315 format.applyPattern(pat); 316 Date date = format.parse(str); 317 String f = format.format(date); 318 logln(" parse(" + str + ") -> " + date.toString()); 319 logln(" format -> " + f); 320 if (expected == null || 321 !date.equals(expected)) { 322 errln("FAIL: Expected " + expected); 323 } 324 if (!f.equals(str)) { 325 errln("FAIL: Expected " + str); 326 } 327 } 328 catch(ParseException e) { 329 logln("ParseException: " + e.getMessage()); 330 if (expected != null) { 331 errln("FAIL: Expected " + expected); 332 } 333 } 334 catch(Exception e) { 335 errln("*** Exception:"); 336 e.printStackTrace(); 337 } 338 } 339 340 // Test pattern with runs things together 341 public void TestRunTogetherPattern985() 342 { 343 String format = "yyyyMMddHHmmssSSS"; 344 String now, then; 345 346 SimpleDateFormat formatter = new SimpleDateFormat(format); 347 348 Date date1 = new Date(); 349 now = formatter.format(date1); 350 351 logln(now); 352 353 ParsePosition pos = new ParsePosition(0); 354 355 Date date2 = formatter.parse(now, pos); 356 if (date2 == null) { 357 then = "Parse stopped at " + pos.getIndex(); 358 } else { 359 then = formatter.format(date2); 360 } 361 362 logln(then); 363 364 if (!date2.equals(date1)) { 365 errln("FAIL"); 366 } 367 } 368 369 // Test patterns which run numbers together 370 @SuppressWarnings("deprecation") 371 public void TestRunTogetherPattern917() 372 { 373 SimpleDateFormat fmt; 374 String myDate; 375 376 fmt = new SimpleDateFormat( "yyyy/MM/dd" ); 377 myDate = "1997/02/03"; 378 _testIt917( fmt, myDate, new Date(97, 2-1, 3) ); 379 380 fmt = new SimpleDateFormat( "yyyyMMdd" ); 381 myDate = "19970304"; 382 _testIt917( fmt, myDate, new Date(97, 3-1, 4) ); 383 384 } 385 void _testIt917( SimpleDateFormat fmt, String str, Date expected ) 386 { 387 logln( "pattern=" + fmt.toPattern() + " string=" + str ); 388 389 Object o; 390 try { 391 o = fmt.parseObject( str ); 392 } catch( ParseException e ) { 393 e.printStackTrace(); 394 return; 395 } 396 logln( "Parsed object: " + o ); 397 if (!o.equals(expected)) { 398 errln("FAIL: Expected " + expected); 399 } 400 401 String formatted = fmt.format( o ); 402 logln( "Formatted string: " + formatted ); 403 if (!formatted.equals(str)) { 404 errln("FAIL: Expected " + str); 405 } 406 } 407 408 // Test Czech month formatting -- this can cause a problem because the June and 409 // July month names share a common prefix. 410 @SuppressWarnings("deprecation") 411 public void TestCzechMonths459() 412 { 413 // Use Czech, which has month names with shared prefixes for June and July 414 DateFormat fmt = DateFormat.getDateInstance(DateFormat.FULL, new Locale("cs", "", "")); 415 //((SimpleDateFormat)fmt).applyPattern("MMMM d yyyy"); 416 logln("Pattern " + ((SimpleDateFormat)fmt).toPattern()); 417 418 Date june = new Date(97, Calendar.JUNE, 15); 419 Date july = new Date(97, Calendar.JULY, 15); 420 421 String juneStr = fmt.format(june); 422 String julyStr = fmt.format(july); 423 424 try { 425 logln("format(June 15 1997) = " + juneStr); 426 Date d = fmt.parse(juneStr); 427 String s = fmt.format(d); 428 int month = d.getMonth(); 429 logln(" -> parse -> " + s + " (month = " + month + ")"); 430 if (month != JUNE) { 431 errln("FAIL: Month should be June"); 432 } 433 434 logln("format(July 15 1997) = " + julyStr); 435 d = fmt.parse(julyStr); 436 s = fmt.format(d); 437 month = d.getMonth(); 438 logln(" -> parse -> " + s + " (month = " + month + ")"); 439 if (month != JULY) { 440 errln("FAIL: Month should be July"); 441 } 442 } 443 catch (ParseException e) { 444 errln("Exception: " + e); 445 } 446 } 447 448 // Test big D (day of year) versus little d (day of month) 449 @SuppressWarnings("deprecation") 450 public void TestLetterDPattern212() 451 { 452 String dateString = "1995-040.05:01:29"; 453 String bigD = "yyyy-DDD.hh:mm:ss"; 454 String littleD = "yyyy-ddd.hh:mm:ss"; 455 Date expLittleD = new Date(95, 0, 1, 5, 1, 29); 456 Date expBigD = new Date(expLittleD.getTime() + 39*24*3600000L); // 39 days 457 expLittleD = expBigD; // Expect the same, with default lenient parsing 458 logln( "dateString= " + dateString ); 459 SimpleDateFormat formatter = new SimpleDateFormat(bigD); 460 ParsePosition pos = new ParsePosition(0); 461 Date myDate = formatter.parse( dateString, pos ); 462 logln("Using " + bigD + " -> " + myDate); 463 if (myDate.getTime() != expBigD.getTime()) { 464 errln("FAIL: Expected " + expBigD + " got " + myDate); 465 } 466 467 formatter = new SimpleDateFormat(littleD); 468 pos = new ParsePosition(0); 469 myDate = formatter.parse( dateString, pos ); 470 logln("Using " + littleD + " -> " + myDate); 471 if (myDate.getTime() != expLittleD.getTime()) { 472 errln("FAIL: Expected " + expLittleD + " got " + myDate); 473 } 474 } 475 476 // Test the 'G' day of year pattern 477 @SuppressWarnings("deprecation") 478 public void TestDayOfYearPattern195() 479 { 480 Date today = new Date(); 481 Date expected = new Date(today.getYear(), today.getMonth(), today.getDate()); 482 483 logln("Test Date: " + today); 484 485 SimpleDateFormat sdf = 486 (SimpleDateFormat)SimpleDateFormat.getDateInstance(); 487 488 tryPattern(sdf, today, null, expected); 489 tryPattern(sdf, today, "G yyyy DDD", expected); 490 } 491 492 void tryPattern(SimpleDateFormat sdf, Date d, String pattern, Date expected) 493 { 494 if (pattern != null) { 495 sdf.applyPattern(pattern); 496 } 497 logln("pattern: " + sdf.toPattern()); 498 499 String formatResult = sdf.format(d); 500 logln(" format -> " + formatResult); 501 try { 502 Date d2 = sdf.parse(formatResult); 503 logln(" parse(" + formatResult + ") -> " + d2); 504 if (d2.getTime() != expected.getTime()) { 505 errln("FAIL: Expected " + expected); 506 } 507 String format2 = sdf.format(d2); 508 logln(" format -> " + format2); 509 if (!formatResult.equals(format2)) { 510 errln("FAIL: Round trip drift"); 511 } 512 } 513 catch(Exception e) { 514 errln("Error: " + e.getMessage()); 515 } 516 } 517 518 // Test a pattern with single quotes 519 @SuppressWarnings("deprecation") 520 public void TestQuotePattern161() 521 { 522 // This pattern used to end in " zzz" but that makes this test zone-dependent 523 SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy 'at' hh:mm:ss a zzz"); 524 Date currentTime_1 = new Date(97, Calendar.AUGUST, 13, 10, 42, 28); 525 String dateString = formatter.format(currentTime_1); 526 String exp = "08/13/1997 at 10:42:28 AM "; 527 logln("format(" + currentTime_1 + ") = " + dateString); 528 if (!dateString.regionMatches(0, exp, 0, exp.length())) { 529 errln("FAIL: Expected " + exp); 530 } 531 } 532 533 // Test the parsing of bad input strings 534 /** Demonstrates a number of bugs in DateFormat.parse(String) where 535 * either StringIndexOutOfBoundsException is thrown or null is 536 * returned instead of ParseException. To reproduce, run this program 537 * and notice all the "SHOULD NOT HAPPEN" errors. Note also that the 538 * 1 line that should be correct is off by 100 years. (In this day 539 * and age, no one would assume that 1/1/00 is Jan 1 1900.) 540 **/ 541 public void TestBadInput135() 542 { 543 int looks[] = { DateFormat.SHORT, DateFormat.MEDIUM, 544 DateFormat.LONG, DateFormat.FULL }; 545 String strings[] = { "Mar 15", "Mar 15 1997", "asdf", 546 "3/1/97 1:23:", "3/1/00 1:23:45 AM" }; 547 DateFormat full = DateFormat.getDateTimeInstance(DateFormat.LONG, 548 DateFormat.LONG); 549 String expected = "March 1, 2000 1:23:45 AM "; 550 for ( int i = 0; i < strings.length; ++i ){ 551 String text = strings[i]; 552 for ( int j = 0; j < looks.length; ++j ){ 553 int dateLook = looks[j]; 554 for ( int k = 0; k < looks.length; ++k ){ 555 int timeLook = looks[k]; 556 DateFormat df = DateFormat.getDateTimeInstance(dateLook, timeLook); 557 String prefix = text + ", " + dateLook + "/" + timeLook + ": "; 558 try { 559 Date when = df.parse(text); 560 if ( when == null ){ 561 errln(prefix + 562 "SHOULD NOT HAPPEN: parse returned null."); 563 continue; 564 } 565 String format = full.format(when); 566 logln(prefix + "OK: " + format); 567 // Only match the start -- not the zone, which could vary 568 if (!format.regionMatches(0, expected, 0, expected.length())) { 569 errln("FAIL: Expected " + expected); 570 } 571 } 572 catch ( ParseException e ){ 573 //errln(prefix + e); // This is expected. 574 } 575 catch ( StringIndexOutOfBoundsException e ){ 576 errln(prefix + "SHOULD NOT HAPPEN: " + e); 577 } 578 } 579 } 580 } 581 } 582 583 final private static String parseFormats[] = 584 { 585 "MMMM d, yyyy", // january 1, 1970 or jan 1, 1970 586 "MMMM d yyyy", // january 1 1970 or jan 1 1970 587 "M/d/yy", // 1/1/70 588 "d MMMM, yyyy", // 1 january, 1970 or 1 jan, 1970 589 "d MMMM yyyy", // 1 january 1970 or 1 jan 1970 590 "d MMMM", // 1 january or 1 jan 591 "MMMM d", // january 1 or jan 1 592 "yyyy", // 1970 593 "h:mm a MMMM d, yyyy" // Date and Time 594 }; 595 final private static String inputStrings[] = 596 { 597 "bogus string", null, null, null, null, null, null, null, null, null, 598 "April 1, 1997", "April 1, 1997", null, null, null, null, null, "April 1", null, null, 599 "Jan 1, 1970", "January 1, 1970", null, null, null, null, null, "January 1", null, null, 600 "Jan 1 2037", null, "January 1 2037", null, null, null, null, "January 1", null, null, 601 "1/1/70", null, null, "1/1/70", null, null, null, null, "0001", null, 602 "5 May 1997", null, null, null, null, "5 May 1997", "5 May", null, "0005", null, 603 "16 May", null, null, null, null, null, "16 May", null, "0016", null, 604 "April 30", null, null, null, null, null, null, "April 30", null, null, 605 "1998", null, null, null, null, null, null, null, "1998", null, 606 "1", null, null, null, null, null, null, null, "0001", null, // Bug620 607 "3:00 pm Jan 1, 1997", null, null, null, null, null, null, null, "0003", "3:00 PM January 1, 1997", 608 }; 609 // More testing of the parsing of bad input 610 @SuppressWarnings("UnusedAssignment") 611 public void TestBadInput135a() 612 { 613 SimpleDateFormat dateParse = new SimpleDateFormat(); 614 String s; 615 Date date; 616 int PFLENGTH = parseFormats.length; 617 618 dateParse.applyPattern("d MMMM, yyyy"); 619 dateParse.setTimeZone(TimeZone.getDefault()); 620 s = "not parseable"; 621 logln("Trying to parse \"" + s + "\" with " + dateParse.toPattern()); 622 try { 623 date = dateParse.parse(s); 624 errln("FAIL: Expected exception during parse"); 625 } catch (Exception ex) { 626 logln("Exception during parse: " + ex); // This is expected 627 } 628 629 for (int i=0; i<inputStrings.length; i += (PFLENGTH+1)) 630 { 631 ParsePosition parsePosition = new ParsePosition(0); 632 s = inputStrings[i]; 633 634 for (int index=0; index<PFLENGTH; ++index) 635 { 636 String expected = inputStrings[i + 1 + index]; 637 dateParse.applyPattern(parseFormats[index]); 638 dateParse.setTimeZone(TimeZone.getDefault()); 639 // logln("Trying to parse \"" + s + "\" with " + dateParse.toPattern()); 640 try { 641 parsePosition.setIndex(0); 642 date = dateParse.parse(s, parsePosition); 643 if (parsePosition.getIndex() != 0) { 644 if (date == null) { 645 errln("ERROR: null result with pos " + 646 parsePosition.getIndex() + " " + 647 s.substring(0, parsePosition.getIndex()) + "|" + 648 s.substring(parsePosition.getIndex())); 649 } else { 650 String result = dateParse.format(date); 651 logln("Parsed \"" + s + "\" using \"" + dateParse.toPattern() + 652 "\" to: " + result); 653 if (expected == null) { 654 errln("FAIL: Expected parse failure"); 655 } else if (!expected.equals(result)) { 656 errln("FAIL: Expected " + expected); 657 } 658 } 659 } else { 660 // logln("Not parsed."); 661 if (expected != null) { 662 errln("FAIL: Expected " + expected); 663 } 664 } 665 } catch (Exception ex) { 666 errln("An exception was thrown during parse: " + ex); 667 } 668 } 669 } 670 } 671 672 // Test the handling of 2-digit dates 673 public void TestTwoDigitYear() { 674 SimpleDateFormat fmt = new SimpleDateFormat("M/d/yy"); 675 676 // find out the expected 2-digit year values for "6/5/17" and "6/4/34" 677 long start = fmt.get2DigitYearStart().getTime(); 678 Calendar cal = new Calendar.Builder().setInstant(start).build(); 679 int startYear = cal.get(YEAR); 680 cal.add(YEAR, 100); 681 long end = cal.getTimeInMillis(); 682 int endYear = cal.get(YEAR); 683 int xx17 = 0, xx34 = 0; 684 for (int year = startYear; year <= endYear; year++) { 685 int yy = year % 100; 686 if (yy == 17 && xx17 == 0) { 687 xx17 = yearValue(start, end, year, JUNE, 5); 688 } else if (yy == 34 && xx34 == 0) { 689 xx34 = yearValue(start, end, year, JUNE, 4); 690 } 691 if (xx17 != 0 && xx34 != 0) { 692 break; 693 } 694 } 695 if (xx17 == 0 || xx34 == 0) { 696 errln("Failed: producing expected values: 2DigitYearStart: " + new Date(start) 697 + ", xx17 = " + xx17 + ", xx34 = " + xx34); 698 } 699 logln("2DigitYearStart: " + new Date(start) + ", xx17 = " + xx17 + ", xx34 = " + xx34); 700 701 parse2DigitYear(fmt, "6/5/17", new GregorianCalendar(xx17, JUNE, 5).getTime()); 702 parse2DigitYear(fmt, "6/4/34", new GregorianCalendar(xx34, JUNE, 4).getTime()); 703 } 704 705 private int yearValue(long start, long end, int year, int month, int dayOfMonth) { 706 Calendar cal = new GregorianCalendar(year, month, dayOfMonth); 707 long time = cal.getTimeInMillis(); 708 return (start <= time && time < end) ? year : 0; 709 } 710 711 private void parse2DigitYear(SimpleDateFormat fmt, String str, Date expected) { 712 try { 713 Date d = fmt.parse(str); 714 logln("Parsing \"" + str + "\" with " + 715 fmt.toPattern() + 716 " => " + d.toString()); 717 if (d.getTime() != expected.getTime()) { 718 errln("FAIL: Expected " + expected); 719 } 720 } catch (ParseException e) { 721 errln("FAIL: Got exception"); 722 } 723 } 724 725 // Test behavior of DateFormat with applied time zone 726 public void TestDateFormatZone061() 727 { 728 Date date; 729 DateFormat formatter; 730 731 // 25-Mar-97 00:00:00 GMT 732 date = new Date( 859248000000L ); 733 logln( "Date 1997/3/25 00:00 GMT: " + date ); 734 formatter = new SimpleDateFormat("dd-MMM-yyyyy HH:mm", Locale.UK); 735 formatter.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); 736 737 String temp = formatter.format( date ); 738 logln( "Formatted in GMT to: " + temp ); 739 740 /* Parse date string */ 741 try { 742 Date tempDate = formatter.parse( temp ); 743 logln( "Parsed to: " + tempDate ); 744 if (tempDate.getTime() != date.getTime()) { 745 errln("FAIL: Expected " + date); 746 } 747 } 748 catch( Throwable t ) { 749 errln( "Date Formatter throws: " + 750 t.toString() ); 751 } 752 } 753 754 // Make sure DateFormat uses the correct zone. 755 public void TestDateFormatZone146() 756 { 757 TimeZone saveDefault = TimeZone.getDefault(); 758 759 try { 760 TimeZone thedefault = TimeZone.getTimeZone("GMT"); 761 TimeZone.setDefault(thedefault); 762 // java.util.Locale.setDefault(new java.util.Locale("ar", "", "")); 763 764 // check to be sure... its GMT all right 765 TimeZone testdefault = TimeZone.getDefault(); 766 String testtimezone = testdefault.getID(); 767 if (testtimezone.equals("GMT")) { 768 logln("Test timezone = " + testtimezone); 769 } else { 770 errln("Test timezone should be GMT, not " + testtimezone); 771 } 772 773 // now try to use the default GMT time zone 774 GregorianCalendar greenwichcalendar = 775 new GregorianCalendar(1997, 3, 4, 23, 0); 776 //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault()); 777 //greenwichcalendar.set(1997, 3, 4, 23, 0); 778 // try anything to set hour to 23:00 !!! 779 greenwichcalendar.set(Calendar.HOUR_OF_DAY, 23); 780 // get time 781 Date greenwichdate = greenwichcalendar.getTime(); 782 // format every way 783 String[] DATA = { 784 "simple format: ", "04/04/97 23:00 GMT", 785 "MM/dd/yy HH:mm z", 786 "full format: ", "Friday, April 4, 1997 11:00:00 o'clock PM GMT", 787 "EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z", 788 "long format: ", "April 4, 1997 11:00:00 PM GMT", 789 "MMMM d, yyyy h:mm:ss a z", 790 "default format: ", "04-Apr-97 11:00:00 PM", 791 "dd-MMM-yy h:mm:ss a", 792 "short format: ", "4/4/97 11:00 PM", 793 "M/d/yy h:mm a", 794 }; 795 796 for (int i=0; i<DATA.length; i+=3) { 797 DateFormat fmt = new SimpleDateFormat(DATA[i+2], Locale.ENGLISH); 798 fmt.setCalendar(greenwichcalendar); 799 String result = fmt.format(greenwichdate); 800 logln(DATA[i] + result); 801 if (!result.equals(DATA[i+1])) { 802 errln("FAIL: Expected " + DATA[i+1] 803 + ", got " + result); 804 } 805 } 806 } 807 finally { 808 TimeZone.setDefault(saveDefault); 809 } 810 } 811 812 /* HS : Commented out for now, need to be changed not to use hardcoded results. 813 public void TestLocaleDateFormat() // Bug 495 814 { 815 Date testDate = new Date (97, Calendar.SEPTEMBER, 15); 816 DateFormat dfFrench = DateFormat.getDateTimeInstance(DateFormat.FULL, 817 DateFormat.FULL, Locale.FRENCH); 818 DateFormat dfUS = DateFormat.getDateTimeInstance(DateFormat.FULL, 819 DateFormat.FULL, Locale.US); 820 String expectedFRENCH = "lundi 15 septembre 1997 00 h 00 GMT-07:00"; 821 String expectedUS = "Monday, September 15, 1997 12:00:00 o'clock AM PDT"; 822 logln("Date set to : " + testDate); 823 String out = dfFrench.format(testDate); 824 logln("Date Formated with French Locale " + out); 825 if (!out.equals(expectedFRENCH)) errln("FAIL: Expected " + expectedFRENCH); 826 out = dfUS.format(testDate); 827 logln("Date Formated with US Locale " + out); 828 if (!out.equals(expectedUS)) errln("FAIL: Expected " + expectedUS); 829 } 830 */ 831 /** 832 * Bug 4056591 833 */ 834 /* 835 test commented out pending API-change approval 836 public void Test2YearStartDate() throws ParseException 837 { 838 // create a SimpleDateFormat to test with; dump out if it's not a SimpleDateFormat 839 DateFormat test = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); 840 841 if (!(test instanceof SimpleDateFormat)) { 842 errln("DateFormat.getInstance() didn't return an instance of SimpleDateFormat!"); 843 return; 844 } 845 846 SimpleDateFormat sdf = (SimpleDateFormat)test; 847 String testString1 = "3/10/67"; 848 String testString2 = "3/16/43"; 849 String testString3 = "7/21/43"; 850 851 // set 2-digit start date to 1/1/1900 852 Calendar cal = Calendar.getInstance(Locale.US); 853 cal.set(1900, 0, 1); 854 sdf.set2DigitStartDate(cal.getTime()); 855 856 // check to make sure get2DigitStartDate() returns the value we passed to 857 // set2DigitStartDate() 858 Date date = sdf.get2DigitStartDate(); 859 cal.setTime(date); 860 if (cal.get(Calendar.YEAR) != 1900 || cal.get(Calendar.MONTH) != 0 || 861 cal.get(Calendar.DATE) != 1) 862 errln("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) 863 + 1) + "/" + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR) + 864 " instead of 1/1/1900."); 865 866 // try parsing "3/10/67" and "3/16/43" with the 2-digit start date set to 1/1/1900 867 date = sdf.parse(testString1); 868 cal.setTime(date); 869 if (cal.get(Calendar.YEAR) != 1967) 870 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 yielded a year of " 871 + cal.get(Calendar.YEAR) + " instead of 1967."); 872 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) 873 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 failed: got " + 874 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 875 " instead of 3/10."); 876 date = sdf.parse(testString2); 877 cal.setTime(date); 878 if (cal.get(Calendar.YEAR) != 1943) 879 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 yielded a year of " 880 + cal.get(Calendar.YEAR) + " instead of 1943."); 881 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) 882 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 failed: got " + 883 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 884 " instead of 3/16."); 885 886 // try parsing "3/10/67" and "3/16/43" with the 2-digit start date set to 1/1/2000 887 cal.set(2000, 0, 1); 888 sdf.set2DigitStartDate(cal.getTime()); 889 date = sdf.parse(testString1); 890 cal.setTime(date); 891 if (cal.get(Calendar.YEAR) != 2067) 892 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 yielded a year of " 893 + cal.get(Calendar.YEAR) + " instead of 2067."); 894 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) 895 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 failed: got " + 896 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 897 " instead of 3/10."); 898 date = sdf.parse(testString2); 899 cal.setTime(date); 900 if (cal.get(Calendar.YEAR) != 2043) 901 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 yielded a year of " 902 + cal.get(Calendar.YEAR) + " instead of 1943."); 903 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) 904 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 failed: got " + 905 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 906 " instead of 3/16."); 907 908 // try parsing "3/10/67" and "3/16/43" with the 2-digit start date set to 1/1/1950 909 cal.set(1950, 0, 1); 910 sdf.set2DigitStartDate(cal.getTime()); 911 date = sdf.parse(testString1); 912 cal.setTime(date); 913 if (cal.get(Calendar.YEAR) != 1967) 914 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 yielded a year of " 915 + cal.get(Calendar.YEAR) + " instead of 1967."); 916 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) 917 errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 failed: got " + 918 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 919 " instead of 3/10."); 920 date = sdf.parse(testString2); 921 cal.setTime(date); 922 if (cal.get(Calendar.YEAR) != 2043) 923 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 yielded a year of " 924 + cal.get(Calendar.YEAR) + " instead of 1943."); 925 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) 926 errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 failed: got " + 927 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 928 " instead of 3/16."); 929 930 // try parsing "3/16/43" and "7/21/43" with the 2-digit start date set to 6/1/1943 931 cal.set(1943, 5, 1); 932 sdf.set2DigitStartDate(cal.getTime()); 933 date = sdf.parse(testString2); 934 cal.setTime(date); 935 if (cal.get(Calendar.YEAR) != 2043) 936 errln("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 yielded a year of " 937 + cal.get(Calendar.YEAR) + " instead of 2043."); 938 if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) 939 errln("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 failed: got " + 940 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 941 " instead of 3/16."); 942 date = sdf.parse(testString3); 943 cal.setTime(date); 944 if (cal.get(Calendar.YEAR) != 1943) 945 errln("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 yielded a year of " 946 + cal.get(Calendar.YEAR) + " instead of 1943."); 947 if (cal.get(Calendar.MONTH) != 6 || cal.get(Calendar.DATE) != 21) 948 errln("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 failed: got " + 949 (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + 950 " instead of 7/21."); 951 952 // and finally, check one more time to make sure get2DigitStartDate() returns the last 953 // value we passed to set2DigitStartDate() 954 date = sdf.get2DigitStartDate(); 955 cal.setTime(date); 956 if (cal.get(Calendar.YEAR) != 1943 || cal.get(Calendar.MONTH) != 5 || 957 cal.get(Calendar.DATE) != 1) 958 errln("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) 959 + 1) + "/" + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR) + 960 " instead of 6/1/1943."); 961 } 962 */ 963 964 /** 965 * ParsePosition.errorIndex tests. 966 */ 967 @SuppressWarnings("deprecation") 968 public void Test4052223() 969 { 970 String str = "7/SOS/2001"; 971 Date exp = new Date(101, Calendar.SEPTEMBER, 7); 972 String pat = "d/MMM/yy"; 973 SimpleDateFormat sdf = new SimpleDateFormat(pat); 974 ParsePosition pos = new ParsePosition(0); 975 Date d = sdf.parse(str, pos); 976 logln(str + " parses with " + pat + " to " + d); 977 if (d == null && pos.getErrorIndex() == 2) { 978 logln("Expected null returned, failed at : " + pos.getErrorIndex()); 979 } else { 980 errln("Failed, parse " + str + " got : " + d + ", index=" + pos.getErrorIndex()); 981 } 982 } 983 984 /** 985 * Bug4469904 -- th_TH date format doesn't use Thai B.E. 986 */ 987 public void TestBuddhistEraBugId4469904() { 988 String era = "\u0e1e.\u0e28."; 989 Locale loc = new Locale("th", "TH"); 990 Calendar cal = Calendar.getInstance(Locale.US); 991 cal.set(2001, 7, 23); 992 Date date = cal.getTime(); 993 DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, loc); 994 String output = df.format(date); 995 int index = output.indexOf(era); 996 if (index == -1) { 997 errln("Test4469904: Failed. Buddhist Era abbrev not present."); 998 } 999 } 1000 1001 /** 1002 * 4326988: API: SimpleDateFormat throws NullPointerException when parsing with null pattern 1003 */ 1004 @SuppressWarnings("UnusedAssignment") 1005 public void Test4326988() { 1006 String[] wrongPatterns = { 1007 "hh o''clock", 1008 "hh 'o''clock", // unterminated quote 1009 "''''''''''''oclock", 1010 "efgxyz", 1011 }; 1012 String[] goodPatterns = { 1013 "hh 'o''clock'", 1014 "'''''''''''''o'", 1015 "'efgxyz'", 1016 ":;,.-", 1017 }; 1018 1019 // Check NullPointerException 1020 try { 1021 SimpleDateFormat fmt = new SimpleDateFormat(null); 1022 errln("SimpleDateFormat() doesn't throw NPE with null pattern"); 1023 } catch (NullPointerException e) { 1024 // Okay 1025 } 1026 try { 1027 Locale loc = null; 1028 SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd", loc); 1029 errln("SimpleDateFormat() doesn't throw NPE with null locale"); 1030 } catch (NullPointerException e) { 1031 // Okay 1032 } 1033 try { 1034 DateFormatSymbols symbols = null; 1035 SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd", symbols); 1036 errln("SimpleDateFormat() doesn't throw NPE with null DateFormatSymbols"); 1037 } catch (NullPointerException e) { 1038 // Okay 1039 } 1040 try { 1041 SimpleDateFormat fmt = new SimpleDateFormat(); 1042 fmt.applyPattern(null); 1043 errln("applyPattern() doesn't throw NPE with null pattern"); 1044 } catch (NullPointerException e) { 1045 // Okay 1046 } 1047 1048 // Check IllegalParameterException 1049 for (int i = 0; i < wrongPatterns.length; i++) { 1050 try { 1051 SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i]); 1052 errln("SimpleDateFormat(\"" + wrongPatterns[i] + "\")" + 1053 " doesn't throw an IllegalArgumentException"); 1054 } catch (IllegalArgumentException e) { 1055 // Okay 1056 } 1057 try { 1058 SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i], 1059 DateFormatSymbols.getInstance()); 1060 errln("SimpleDateFormat(\"" + wrongPatterns[i] + "\", DateFormatSymbols) doesn't " + 1061 "throw an IllegalArgumentException"); 1062 } catch (IllegalArgumentException e) { 1063 // Okay 1064 } 1065 try { 1066 SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i], 1067 Locale.US); 1068 errln("SimpleDateFormat(\"" + wrongPatterns[i] + 1069 "\", Locale) doesn't throw an IllegalArgumentException"); 1070 } catch (IllegalArgumentException e) { 1071 // Okay 1072 } 1073 try { 1074 SimpleDateFormat fmt = new SimpleDateFormat(); 1075 fmt.applyPattern(wrongPatterns[i]); 1076 errln("SimpleDateFormat.applyPattern(\"" + wrongPatterns[i] + 1077 "\") doesn't throw an IllegalArgumentException"); 1078 } catch (IllegalArgumentException e) { 1079 // Okay 1080 } 1081 } 1082 1083 for (int i = 0; i < goodPatterns.length; i++) { 1084 SimpleDateFormat fmt; 1085 fmt = new SimpleDateFormat(goodPatterns[i]); 1086 fmt = new SimpleDateFormat(goodPatterns[i], 1087 DateFormatSymbols.getInstance()); 1088 fmt = new SimpleDateFormat(goodPatterns[i], 1089 Locale.US); 1090 fmt = new SimpleDateFormat(); 1091 fmt.applyPattern(goodPatterns[i]); 1092 } 1093 } 1094 1095 /** 1096 * 4486735: RFE: SimpleDateFormat performance improvement 1097 * 1098 * Another round trip test 1099 */ 1100 @SuppressWarnings("deprecation") 1101 public void Test4486735() throws Exception { 1102 TimeZone initialTimeZone = TimeZone.getDefault(); 1103 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); 1104 Locale[] locales = Locale.getAvailableLocales(); 1105 String[] zones = { "GMT", "America/Los_Angeles", "Europe/London", "Asia/Tokyo" }; 1106 1107 // Round to minutes. Some FULL formats don't have seconds. 1108 long time = System.currentTimeMillis()/60000 * 60000; 1109 Date date = new Date(time); 1110 logln("the test date: " + date); 1111 1112 try { 1113 for (int z = 0; z < zones.length; z++) { 1114 TimeZone.setDefault(TimeZone.getTimeZone(zones[z])); 1115 for (int i = 0; i < locales.length; i++) { 1116 Locale loc = locales[i]; 1117 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, 1118 DateFormat.FULL, 1119 loc); 1120 String s = df.format(date); 1121 logln(s); 1122 Date parsedDate = df.parse(s); 1123 long parsedTime = parsedDate.getTime(); 1124 if (time != parsedTime) { 1125 // See if the time is in daylight-standard time transition. (JDK-8140571) 1126 // Date-time formats in some locales don't have time zone information. 1127 TimeZone tz = TimeZone.getDefault(); 1128 if (tz.inDaylightTime(date) && !tz.inDaylightTime(parsedDate)) { 1129 if (time == parsedTime - tz.getDSTSavings()) { 1130 // OK (in "fall-back") 1131 continue; 1132 } 1133 } 1134 errln("round trip conversion failed: timezone="+zones[z]+ 1135 ", locale=" + loc + 1136 ", expected=" + time + ", got=" + parsedTime); 1137 } 1138 } 1139 } 1140 1141 // Long format test 1142 String pat = 1143 "'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + // 100 1144 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1145 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + // 200 1146 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1147 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + // 300 1148 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1149 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + // 400 1150 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1151 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + // 500 1152 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'" + 1153 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1154 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1155 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1156 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593':'" + 1157 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1158 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + // 100 1159 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + 1160 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + // 200 1161 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + 1162 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + // 300 1163 "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\u5e74"; 1164 1165 // Note that >4 y's produces just "2001" until 1.3.1. This 1166 // was fixed in 1.4. 1167 String expected = 1168 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1169 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1170 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1171 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1172 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1173 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1174 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1175 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1176 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1177 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + 1178 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1179 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1180 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1181 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1182 "\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:\u6642\u9593:" + 1183 "00000000000000000000000000000000000000000000000000" + 1184 "00000000000000000000000000000000000000000000000000" + 1185 "00000000000000000000000000000000000000000000000000" + 1186 "00000000000000000000000000000000000000000000000000" + 1187 "00000000000000000000000000000000000000000000000000" + 1188 "00000000000000000000000000000000000000000000002001\u5e74"; 1189 SimpleDateFormat sdf = new SimpleDateFormat(pat); 1190 String s = sdf.format(new Date(2001-1900, Calendar.JANUARY, 1)); 1191 if (!expected.equals(s)) { 1192 errln("wrong format result: expected="+expected+", got="+s); 1193 } 1194 Date longday = sdf.parse(s); 1195 GregorianCalendar cal = new GregorianCalendar(); 1196 cal.setTime(longday); 1197 if (cal.get(YEAR) != 2001) { 1198 errln("wrong parse result: expected=2001, got=" + cal.get(YEAR)); 1199 } 1200 } catch (Exception e) { 1201 throw e; 1202 } finally { 1203 // Restore the initial time zone 1204 TimeZone.setDefault(initialTimeZone); 1205 } 1206 } 1207 }