1 21 22 27 28 package javax.mail.internet; 29 30 import java.util.Date ; 31 import java.util.Calendar ; 32 import java.util.GregorianCalendar ; 33 import java.util.Locale ; 34 import java.util.TimeZone ; 35 import java.text.DateFormat ; 36 import java.text.SimpleDateFormat ; 37 import java.text.NumberFormat ; 38 import java.text.FieldPosition ; 39 import java.text.ParsePosition ; 40 import java.text.ParseException ; 41 42 122 123 public class MailDateFormat extends SimpleDateFormat { 124 125 private static final long serialVersionUID = -8148227605210628779L; 126 127 public MailDateFormat() { 128 super("EEE, d MMM yyyy HH:mm:ss 'XXXXX' (z)", Locale.US); 129 } 130 131 141 public StringBuffer format(Date date, StringBuffer dateStrBuf, 142 FieldPosition fieldPosition) { 143 144 151 152 int start = dateStrBuf.length(); 153 super.format(date, dateStrBuf, fieldPosition); 154 int pos = 0; 155 for (pos = start + 25; dateStrBuf.charAt(pos) != 'X'; pos++) 158 ; 159 160 calendar.clear(); 162 calendar.setTime(date); 163 int offset = calendar.get(Calendar.ZONE_OFFSET) + 164 calendar.get(Calendar.DST_OFFSET); 165 if (offset < 0) { 167 dateStrBuf.setCharAt(pos++, '-'); 168 offset = (-offset); 169 } else 170 dateStrBuf.setCharAt(pos++, '+'); 171 172 int rawOffsetInMins = offset / 60 / 1000; int offsetInHrs = rawOffsetInMins / 60; 174 int offsetInMins = rawOffsetInMins % 60; 175 176 dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs/10), 10)); 177 dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs%10), 10)); 178 dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins/10), 10)); 179 dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins%10), 10)); 180 182 return dateStrBuf; 183 } 184 185 187 196 public Date parse(String text, ParsePosition pos) { 197 return parseDate(text.toCharArray(), pos, isLenient()); 198 } 199 200 209 210 240 241 static boolean debug = false; 242 243 246 static private Date parseDate(char[] orig, ParsePosition pos, 247 boolean lenient) { 248 try { 249 int day = -1; 250 int month = -1; 251 int year = -1; 252 int hours = 0; 253 int minutes = 0; 254 int seconds = 0; 255 int offset = 0; 256 257 258 MailDateParser p = new MailDateParser(orig); 259 260 p.skipUntilNumber(); 262 day = p.parseNumber(); 263 264 if (!p.skipIfChar('-')) { p.skipWhiteSpace(); 266 } 267 268 month = p.parseMonth(); 270 if (!p.skipIfChar('-')) { p.skipWhiteSpace(); 272 } 273 274 year = p.parseNumber(); if (year < 50) { 277 year += 2000; 278 } else if (year < 100) { 279 year += 1900; 280 } 282 283 p.skipWhiteSpace(); 286 hours = p.parseNumber(); 287 288 p.skipChar(':'); 290 minutes = p.parseNumber(); 291 292 if (p.skipIfChar(':')) { 294 seconds = p.parseNumber(); 295 } 296 297 298 try { 300 p.skipWhiteSpace(); 301 offset = p.parseTimeZone(); 302 } catch (ParseException pe) { 303 if (debug) { 304 System.out.println("No timezone? : '" + orig + "'"); 305 } 306 } 307 308 pos.setIndex(p.getIndex()); 309 Date d = ourUTC(year, month, day, hours, minutes, seconds, offset, 310 lenient); 311 return d; 312 313 } catch (Exception e) { 314 319 if (debug) { 320 System.out.println("Bad date: '" + orig + "'"); 321 e.printStackTrace(); 322 } 323 pos.setIndex(1); return null; 325 } 326 } 327 328 private static TimeZone tz = TimeZone.getTimeZone("GMT"); 329 private static Calendar cal = new GregorianCalendar (tz); 330 private synchronized static Date ourUTC(int year, int mon, int mday, 331 int hour, int min, int sec, 332 int tzoffset, boolean lenient) { 333 cal.clear(); 335 cal.setLenient(lenient); 336 cal.set(Calendar.YEAR, year); 337 cal.set(Calendar.MONTH, mon); 338 cal.set(Calendar.DATE, mday); 339 cal.set(Calendar.HOUR_OF_DAY, hour); 340 cal.set(Calendar.MINUTE, min + tzoffset); cal.set(Calendar.SECOND, sec); 342 343 return cal.getTime(); 344 } 345 346 347 349 350 public void setCalendar(Calendar newCalendar) { 351 throw new RuntimeException ("Method setCalendar() shouldn't be called"); 352 } 353 354 355 public void setNumberFormat(NumberFormat newNumberFormat) { 356 throw new RuntimeException ("Method setNumberFormat() shouldn't be called"); 357 } 358 359 360 361 436 437 } 438 439 442 class MailDateParser { 443 444 int index = 0; 445 char[] orig = null; 446 447 public MailDateParser(char[] orig) { 448 this.orig = orig; 449 } 450 451 457 public void skipUntilNumber() throws ParseException { 458 try { 459 while (true) { 460 switch ( orig[index] ) { 461 case '0': 462 case '1': 463 case '2': 464 case '3': 465 case '4': 466 case '5': 467 case '6': 468 case '7': 469 case '8': 470 case '9': 471 return; 472 473 default: 474 index++; 475 break; 476 } 477 } 478 } catch (ArrayIndexOutOfBoundsException e) { 479 throw new ParseException ("No Number Found", index); 480 } 481 } 482 483 486 public void skipWhiteSpace() { 487 int len = orig.length; 488 while (index < len) { 489 switch (orig[index]) { 490 case ' ': case '\t': case '\r': case '\n': index++; 495 break; 496 497 default: 498 return; 499 } 500 } 501 } 502 503 504 508 public int peekChar() throws ParseException { 509 if (index < orig.length) 510 return orig[index]; 511 else 512 throw new ParseException ("No more characters", index); 513 } 514 515 519 public void skipChar(char c) throws ParseException { 520 if (index < orig.length) { 521 if (orig[index] == c) { 522 index++; 523 } else { 524 throw new ParseException ("Wrong char", index); 525 } 526 } else { 527 throw new ParseException ("No more characters", index); 528 } 529 } 530 531 535 public boolean skipIfChar(char c) throws ParseException { 536 if (index < orig.length) { 537 if (orig[index] == c) { 538 index++; 539 return true; 540 } else { 541 return false; 542 } 543 } else { 544 throw new ParseException ("No more characters", index); 545 } 546 } 547 548 549 554 public int parseNumber() throws ParseException { 555 int length = orig.length; 556 boolean gotNum = false; 557 int result = 0; 558 559 while (index < length) { 560 switch( orig[index] ) { 561 case '0': 562 result *= 10; 563 gotNum = true; 564 break; 565 566 case '1': 567 result = result * 10 + 1; 568 gotNum = true; 569 break; 570 571 case '2': 572 result = result * 10 + 2; 573 gotNum = true; 574 break; 575 576 case '3': 577 result = result * 10 + 3; 578 gotNum = true; 579 break; 580 581 case '4': 582 result = result * 10 + 4; 583 gotNum = true; 584 break; 585 586 case '5': 587 result = result * 10 + 5; 588 gotNum = true; 589 break; 590 591 case '6': 592 result = result * 10 + 6; 593 gotNum = true; 594 break; 595 596 case '7': 597 result = result * 10 + 7; 598 gotNum = true; 599 break; 600 601 case '8': 602 result = result * 10 + 8; 603 gotNum = true; 604 break; 605 606 case '9': 607 result = result * 10 + 9; 608 gotNum = true; 609 break; 610 611 default: 612 if (gotNum) 613 return result; 614 else 615 throw new ParseException ("No Number found", index); 616 } 617 618 index++; 619 } 620 621 if (gotNum) 623 return result; 624 625 throw new ParseException ("No Number found", index); 627 } 628 629 630 635 public int parseMonth() throws ParseException { 636 char curr; 637 638 try { 639 switch(orig[index++]) { 640 case 'J': 641 case 'j': switch(orig[index++]) { 644 case 'A': 645 case 'a': 646 curr = orig[index++]; 647 if (curr == 'N' || curr == 'n') { 648 return 0; 649 } 650 break; 651 652 case 'U': 653 case 'u': 654 curr = orig[index++]; 655 if (curr == 'N' || curr == 'n') { 656 return 5; 657 } else if (curr == 'L' || curr == 'l') { 658 return 6; 659 } 660 break; 661 } 662 break; 663 664 case 'F': 665 case 'f': curr = orig[index++]; 667 if (curr == 'E' || curr == 'e') { 668 curr = orig[index++]; 669 if (curr == 'B' || curr == 'b') { 670 return 1; 671 } 672 } 673 break; 674 675 case 'M': 676 case 'm': curr = orig[index++]; 678 if (curr == 'A' || curr == 'a') { 679 curr = orig[index++]; 680 if (curr == 'R' || curr == 'r') { 681 return 2; 682 } else if (curr == 'Y' || curr == 'y') { 683 return 4; 684 } 685 } 686 break; 687 688 case 'A': 689 case 'a': curr = orig[index++]; 691 if (curr == 'P' || curr == 'p') { 692 curr = orig[index++]; 693 if (curr == 'R' || curr == 'r') { 694 return 3; 695 } 696 } else if (curr == 'U' || curr == 'u') { 697 curr = orig[index++]; 698 if (curr == 'G' || curr == 'g') { 699 return 7; 700 } 701 } 702 break; 703 704 case 'S': 705 case 's': curr = orig[index++]; 707 if (curr == 'E' || curr == 'e') { 708 curr = orig[index++]; 709 if (curr == 'P' || curr == 'p') { 710 return 8; 711 } 712 } 713 break; 714 715 case 'O': 716 case 'o': curr = orig[index++]; 718 if (curr == 'C' || curr == 'c') { 719 curr = orig[index++]; 720 if (curr == 'T' || curr == 't') { 721 return 9; 722 } 723 } 724 break; 725 726 case 'N': 727 case 'n': curr = orig[index++]; 729 if (curr == 'O' || curr == 'o') { 730 curr = orig[index++]; 731 if (curr == 'V' || curr == 'v') { 732 return 10; 733 } 734 } 735 break; 736 737 case 'D': 738 case 'd': curr = orig[index++]; 740 if (curr == 'E' || curr == 'e') { 741 curr = orig[index++]; 742 if (curr == 'C' || curr == 'c') { 743 return 11; 744 } 745 } 746 break; 747 } 748 } catch (ArrayIndexOutOfBoundsException e) { 749 } 750 751 throw new ParseException ("Bad Month", index); 752 } 753 754 759 public int parseTimeZone() throws ParseException { 760 if (index >= orig.length) 761 throw new ParseException ("No more characters", index); 762 763 char test = orig[index]; 764 if ( test == '+' || test == '-' ) { 765 return parseNumericTimeZone(); 766 } else { 767 return parseAlphaTimeZone(); 768 } 769 } 770 771 772 777 public int parseNumericTimeZone() throws ParseException { 778 boolean switchSign = false; 784 char first = orig[index++]; 785 if (first == '+') { 786 switchSign = true; 787 } else if (first != '-') { 788 throw new ParseException ("Bad Numeric TimeZone", index); 789 } 790 791 int tz = parseNumber(); 792 int offset = (tz / 100) * 60 + (tz % 100); 793 if (switchSign) { 794 return -offset; 795 } else { 796 return offset; 797 } 798 } 799 800 805 public int parseAlphaTimeZone() throws ParseException { 806 int result = 0; 807 boolean foundCommon = false; 808 char curr; 809 810 try { 811 switch(orig[index++]) { 812 case 'U': 813 case 'u': curr = orig[index++]; 815 if (curr == 'T' || curr == 't') { 816 result = 0; 817 break; 818 } 819 throw new ParseException ("Bad Alpha TimeZone", index); 820 821 case 'G': 822 case 'g': curr = orig[index++]; 824 if (curr == 'M' || curr == 'm') { 825 curr = orig[index++]; 826 if (curr == 'T' || curr == 't') { 827 result = 0; 828 break; 829 } 830 } 831 throw new ParseException ("Bad Alpha TimeZone", index); 832 833 case 'E': 834 case 'e': result = 300; 836 foundCommon = true; 837 break; 838 839 case 'C': 840 case 'c': result = 360; 842 foundCommon = true; 843 break; 844 845 case 'M': 846 case 'm': result = 420; 848 foundCommon = true; 849 break; 850 851 case 'P': 852 case 'p': result = 480; 854 foundCommon = true; 855 break; 856 857 default: 858 throw new ParseException ("Bad Alpha TimeZone", index); 859 } 860 } catch (ArrayIndexOutOfBoundsException e) { 861 throw new ParseException ("Bad Alpha TimeZone", index); 862 } 863 864 if (foundCommon) { 865 curr = orig[index++]; 866 if (curr == 'S' || curr == 's') { 867 curr = orig[index++]; 868 if (curr != 'T' && curr != 't') { 869 throw new ParseException ("Bad Alpha TimeZone", index); 870 } 871 } else if (curr == 'D' || curr == 'd') { 872 curr = orig[index++]; 873 if (curr == 'T' || curr != 't') { 874 result -= 60; 876 } else { 877 throw new ParseException ("Bad Alpha TimeZone", index); 878 } 879 } 880 } 881 882 return result; 883 } 884 885 int getIndex() { 886 return index; 887 } 888 } 889 | Popular Tags |