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