1 5 6 package com.ibm.icu.util; 7 import com.ibm.icu.impl.JDKTimeZone; 8 9 import java.io.IOException ; 10 import java.util.Date ; 11 12 import com.ibm.icu.impl.OlsonTimeZone; 13 import com.ibm.icu.impl.Utility; 14 15 33 public class SimpleTimeZone extends JDKTimeZone { 34 private static final long serialVersionUID = -7034676239311322769L; 35 36 47 public SimpleTimeZone(int rawOffset, String ID) { 48 construct(rawOffset, 0, 0, 0, 51 0, WALL_TIME, 52 0, 0, 0, 53 0, WALL_TIME, 54 MILLIS_PER_HOUR); 55 super.setID(ID); 56 } 57 58 116 public SimpleTimeZone(int rawOffset, String ID, 117 int startMonth, int startDay, int startDayOfWeek, int startTime, 118 int endMonth, int endDay, int endDayOfWeek, int endTime) { 119 122 construct(rawOffset, 126 startMonth, startDay, startDayOfWeek, 127 startTime, WALL_TIME, 128 endMonth, endDay, endDayOfWeek, 129 endTime, WALL_TIME, 130 MILLIS_PER_HOUR); 131 super.setID(ID); 132 } 133 134 142 public SimpleTimeZone(int rawOffset, String ID, 143 int startMonth, int startDay, int startDayOfWeek, int startTime, 144 int endMonth, int endDay, int endDayOfWeek, int endTime, 145 int dstSavings) { 146 149 this.raw = rawOffset; 150 this.dst = dstSavings; 151 156 157 construct(rawOffset, 158 startMonth, startDay, startDayOfWeek, 159 startTime, WALL_TIME, 160 endMonth, endDay, endDayOfWeek, 161 endTime, WALL_TIME, 162 dstSavings); 163 super.setID(ID); 164 } 165 166 167 174 public void setRawOffset(int offsetMillis) { 175 raw = offsetMillis; 176 } 177 178 185 public int getRawOffset() { 186 return raw; 187 } 188 189 195 public void setStartYear(int year) { 196 198 getSTZInfo().sy = year; 199 this.startYear = year; 200 } 201 202 223 public void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek, 224 int time) { 225 227 getSTZInfo().setStart(month, dayOfWeekInMonth, dayOfWeek, time, -1, false); 228 setStartRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME); 229 } 230 268 269 private void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time, int mode) 270 { 271 startMonth = month; 272 startDay = dayOfWeekInMonth; 273 startDayOfWeek = dayOfWeek; 274 startTime = time; 275 startTimeMode = mode; 276 decodeStartRule(); 277 } 278 290 public void setStartRule(int month, int dayOfMonth, int time) { 291 293 getSTZInfo().setStart(month, -1, -1, time, dayOfMonth, false); 294 setStartRule(month, dayOfMonth, 0, time, WALL_TIME); 295 } 296 297 314 public void setStartRule(int month, int dayOfMonth, int dayOfWeek, int time, boolean after) { 315 317 getSTZInfo().setStart(month, -1, dayOfWeek, time, dayOfMonth, after); 318 setStartRule(month, after ? dayOfMonth : -dayOfMonth, 319 -dayOfWeek, time, WALL_TIME); 320 321 } 322 323 343 public void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time) { 344 346 getSTZInfo().setEnd(month, dayOfWeekInMonth, dayOfWeek, time, -1, false); 347 setEndRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME); 348 } 349 350 362 public void setEndRule(int month, int dayOfMonth, int time) { 363 365 getSTZInfo().setEnd(month, -1, -1, time, dayOfMonth, false); 366 setEndRule(month, dayOfMonth, WALL_TIME, time); 367 } 368 369 386 public void setEndRule(int month, int dayOfMonth, int dayOfWeek, int time, boolean after) { 387 389 getSTZInfo().setEnd(month, -1, dayOfWeek, time, dayOfMonth, after); 390 setEndRule(month, dayOfMonth, dayOfWeek, time, WALL_TIME, after); 391 } 392 private void setEndRule(int month, int dayOfMonth, int dayOfWeek, 393 int time, int mode, boolean after){ 394 setEndRule(month, after ? dayOfMonth : -dayOfMonth, -dayOfWeek, time, mode); 395 } 396 413 private void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time, int mode){ 414 endMonth = month; 415 endDay = dayOfWeekInMonth; 416 endDayOfWeek = dayOfWeek; 417 endTime = time; 418 endTimeMode = mode; 419 decodeEndRule(); 420 } 421 428 public void setDSTSavings(int millisSavedDuringDST) { 429 if (millisSavedDuringDST <= 0) { 431 throw new IllegalArgumentException (); 432 } 433 dst = millisSavedDuringDST; 434 } 435 436 443 public int getDSTSavings() { 444 return dst; 445 } 446 447 454 public SimpleTimeZone(java.util.SimpleTimeZone tz, String ID) { 455 super(tz); 456 super.setID(ID); 457 dst = tz.getDSTSavings(); 458 raw = tz.getRawOffset(); 459 } 460 461 468 private void readObject(java.io.ObjectInputStream in) throws IOException , ClassNotFoundException { 470 in.defaultReadObject(); 471 String id = getID(); 472 489 492 if (xinfo != null) { 493 xinfo.applyTo(this); 494 } 495 496 } 497 503 public String toString() { 504 return "SimpleTimeZone: " + getID(); 505 } 506 507 private STZInfo getSTZInfo() { 508 if (xinfo == null) { 509 xinfo = new STZInfo(); 510 } 511 return xinfo; 512 } 513 private final byte monthLength[] = staticMonthLength; 519 private final static byte staticMonthLength[] = {31,29,31,30,31,30,31,31,30,31,30,31}; 520 private final static byte staticLeapMonthLength[] = {31,29,31,30,31,30,31,31,30,31,30,31}; 521 522 524 528 public int getOffset(int era, int year, int month, int day, 529 int dayOfWeek, int millis) 530 { 531 if(month < Calendar.JANUARY || month > Calendar.DECEMBER) { 539 throw new IllegalArgumentException (); 540 } 541 542 return getOffset(era, year, month, day, dayOfWeek, millis, staticMonthLength[month]); 543 } 544 545 549 public int getOffset(int era, int year, int month, int day, 550 int dayOfWeek, int millis, 551 int monthLength) { 552 if(month < Calendar.JANUARY || month > Calendar.DECEMBER) { 560 throw new IllegalArgumentException (); 561 } 562 563 int prevMonthLength = (month >= 1) ? staticMonthLength[month - 1] : 31; 565 566 return getOffset(era, year, month, day, dayOfWeek, millis, 567 monthLength, prevMonthLength); 568 } 569 570 int getOffset(int era, int year, int month, int day, 571 int dayOfWeek, int millis, 572 int monthLength, int prevMonthLength ){ 573 574 if (true) { 575 578 if ((era != GregorianCalendar.AD && era != GregorianCalendar.BC) 579 || month < Calendar.JANUARY 580 || month > Calendar.DECEMBER 581 || day < 1 582 || day > monthLength 583 || dayOfWeek < Calendar.SUNDAY 584 || dayOfWeek > Calendar.SATURDAY 585 || millis < 0 586 || millis >= MILLIS_PER_DAY 587 || monthLength < 28 588 || monthLength > 31 589 || prevMonthLength < 28 590 || prevMonthLength > 31) { 591 throw new IllegalArgumentException (); 592 } 593 } else { 594 597 if (era != GregorianCalendar.AD && era != GregorianCalendar.BC) { 598 throw new IllegalArgumentException ("Illegal era " + era); 599 } 600 if (month < Calendar.JANUARY 601 || month > Calendar.DECEMBER) { 602 throw new IllegalArgumentException ("Illegal month " + month); 603 } 604 if (day < 1 605 || day > monthLength) { 606 throw new IllegalArgumentException ("Illegal day " + day+" max month len: "+monthLength); 607 } 608 if (dayOfWeek < Calendar.SUNDAY 609 || dayOfWeek > Calendar.SATURDAY) { 610 throw new IllegalArgumentException ("Illegal day of week " + dayOfWeek); 611 } 612 if (millis < 0 613 || millis >= MILLIS_PER_DAY) { 614 throw new IllegalArgumentException ("Illegal millis " + millis); 615 } 616 if (monthLength < 28 617 || monthLength > 31) { 618 throw new IllegalArgumentException ("Illegal month length " + monthLength); 619 } 620 if (prevMonthLength < 28 621 || prevMonthLength > 31) { 622 throw new IllegalArgumentException ("Illegal previous month length " + prevMonthLength); 623 } 624 } 625 626 int result = raw; 627 628 if (!useDaylight || year < startYear || era != GregorianCalendar.AD) return result; 630 631 boolean southern = (startMonth > endMonth); 634 635 int startCompare = compareToRule(month, monthLength, prevMonthLength, 638 day, dayOfWeek, millis, 639 startTimeMode == UTC_TIME ? -raw : 0, 640 startMode, startMonth, startDayOfWeek, 641 startDay, startTime); 642 int endCompare = 0; 643 644 650 if (southern != (startCompare >= 0)) { 651 654 endCompare = compareToRule(month, monthLength, prevMonthLength, 655 day, dayOfWeek, millis, 656 endTimeMode == WALL_TIME ? dst : 657 (endTimeMode == UTC_TIME ? -raw : 0), 658 endMode, endMonth, endDayOfWeek, 659 endDay, endTime); 660 } 661 662 if ((!southern && (startCompare >= 0 && endCompare < 0)) || 667 (southern && (startCompare >= 0 || endCompare < 0))) 668 result += dst; 669 670 return result; 671 } 672 673 private static final int 675 DOM_MODE = 1, 676 DOW_IN_MONTH_MODE=2, 677 DOW_GE_DOM_MODE=3, 678 DOW_LE_DOM_MODE=4; 679 680 691 private static final int WALL_TIME = 0, 692 STANDARD_TIME = 1, 693 UTC_TIME = 2; 694 695 704 private int compareToRule(int month, int monthLen, int prevMonthLen, 705 int dayOfMonth, 706 int dayOfWeek, int millis, int millisDelta, 707 int ruleMode, int ruleMonth, int ruleDayOfWeek, 708 int ruleDay, int ruleMillis) 709 { 710 712 millis += millisDelta; 713 714 while (millis >= MILLIS_PER_DAY) { 715 millis -= MILLIS_PER_DAY; 716 ++dayOfMonth; 717 dayOfWeek = 1 + (dayOfWeek % 7); if (dayOfMonth > monthLen) { 719 dayOfMonth = 1; 720 724 ++month; 725 } 726 } 727 while (millis < 0) { 728 millis += MILLIS_PER_DAY; 729 --dayOfMonth; 730 dayOfWeek = 1 + ((dayOfWeek+5) % 7); if (dayOfMonth < 1) { 732 dayOfMonth = prevMonthLen; 733 --month; 734 } 735 } 736 737 if (month < ruleMonth) return -1; 738 else if (month > ruleMonth) return 1; 739 740 int ruleDayOfMonth = 0; 741 switch (ruleMode) 742 { 743 case DOM_MODE: 744 ruleDayOfMonth = ruleDay; 745 break; 746 case DOW_IN_MONTH_MODE: 747 if (ruleDay > 0) 749 ruleDayOfMonth = 1 + (ruleDay - 1) * 7 + 750 (7 + ruleDayOfWeek - (dayOfWeek - dayOfMonth + 1)) % 7; 751 else { 753 ruleDayOfMonth = monthLen + (ruleDay + 1) * 7 - 754 (7 + (dayOfWeek + monthLen - dayOfMonth) - ruleDayOfWeek) % 7; 755 } 756 break; 757 case DOW_GE_DOM_MODE: 758 ruleDayOfMonth = ruleDay + 759 (49 + ruleDayOfWeek - ruleDay - dayOfWeek + dayOfMonth) % 7; 760 break; 761 case DOW_LE_DOM_MODE: 762 ruleDayOfMonth = ruleDay - 763 (49 - ruleDayOfWeek + ruleDay + dayOfWeek - dayOfMonth) % 7; 764 break; 767 } 768 769 if (dayOfMonth < ruleDayOfMonth) return -1; 770 else if (dayOfMonth > ruleDayOfMonth) return 1; 771 772 if (millis < ruleMillis){ 773 return -1; 774 }else if (millis > ruleMillis){ 775 return 1; 776 }else{ 777 return 0; 778 } 779 } 780 private int raw; private int dst = 3600000; 783 private STZInfo xinfo = null; 784 private int startMonth, startDay, startDayOfWeek; private int startTime; 786 private int startTimeMode, endTimeMode; private int endMonth, endDay, endDayOfWeek; private int endTime; 789 private int startYear; private boolean useDaylight; private int startMode, endMode; 793 797 public boolean useDaylightTime(){ 798 return useDaylight; 799 } 800 801 805 public boolean inDaylightTime(Date date){ 806 GregorianCalendar gc = new GregorianCalendar(this); 807 gc.setTime(date); 808 return gc.inDaylightTime(); 809 } 810 811 815 public SimpleTimeZone(int raw, String ID, 816 int startMonth, int startDay, 817 int startDayOfWeek, int startTime, 818 int startTimeMode, 819 int endMonth, int endDay, 820 int endDayOfWeek, int endTime, 821 int endTimeMode,int dst){ 822 825 construct(raw, 826 startMonth, startDay, startDayOfWeek, 827 startTime, startTimeMode, 828 endMonth, endDay, endDayOfWeek, 829 endTime, endTimeMode, 830 dst); 831 } 832 833 849 866 869 private void construct(int raw, 870 int startMonth, 871 int startDay, 872 int startDayOfWeek, 873 int startTime, 874 int startTimeMode, 875 int endMonth, 876 int endDay, 877 int endDayOfWeek, 878 int endTime, 879 int endTimeMode, 880 int dst) { 881 this.raw = raw; 882 this.startMonth = startMonth; 883 this.startDay = startDay; 884 this.startDayOfWeek = startDayOfWeek; 885 this.startTime = startTime; 886 this.startTimeMode = startTimeMode; 887 this.endMonth = endMonth; 888 this.endDay = endDay; 889 this.endDayOfWeek = endDayOfWeek; 890 this.endTime = endTime; 891 this.endTimeMode = endTimeMode; 892 this.dst = dst; 893 this.startYear = 0; 894 this.startMode = DOM_MODE; 895 this.endMode = DOM_MODE; 896 897 decodeRules(); 898 899 if (dst <= 0) { 900 throw new IllegalArgumentException (); 901 } 902 } 903 private void decodeRules(){ 904 decodeStartRule(); 905 decodeEndRule(); 906 } 907 908 932 private void decodeStartRule() { 933 934 useDaylight = (boolean)((startDay != 0) && (endDay != 0) ? true : false ); 935 if (useDaylight && dst == 0) { 936 dst = TimeZone.MILLIS_PER_DAY; 937 } 938 if (startDay != 0) { 939 if (startMonth < Calendar.JANUARY || startMonth > Calendar.DECEMBER) { 940 throw new IllegalArgumentException (); 941 } 942 if (startTime < 0 || startTime >= TimeZone.MILLIS_PER_DAY || 943 startTimeMode < WALL_TIME || startTimeMode > UTC_TIME) { 944 throw new IllegalArgumentException (); 945 } 946 if (startDayOfWeek == 0) { 947 startMode = DOM_MODE; 948 } else { 949 if (startDayOfWeek > 0) { 950 startMode = DOW_IN_MONTH_MODE; 951 } else { 952 startDayOfWeek = (int)-startDayOfWeek; 953 if (startDay > 0) { 954 startMode = DOW_GE_DOM_MODE; 955 } else { 956 startDay = (int)-startDay; 957 startMode = DOW_LE_DOM_MODE; 958 } 959 } 960 if (startDayOfWeek > Calendar.SATURDAY) { 961 throw new IllegalArgumentException (); 962 } 963 } 964 if (startMode == DOW_IN_MONTH_MODE) { 965 if (startDay < -5 || startDay > 5) { 966 throw new IllegalArgumentException (); 967 } 968 } else if (startDay < 1 || startDay > staticMonthLength[startMonth]) { 969 throw new IllegalArgumentException (); 970 } 971 } 972 } 973 974 979 private void decodeEndRule() { 980 useDaylight = (boolean)((startDay != 0) && (endDay != 0) ? true : false); 981 if (useDaylight && dst == 0) { 982 dst = TimeZone.MILLIS_PER_DAY; 983 } 984 if (endDay != 0) { 985 if (endMonth < Calendar.JANUARY || endMonth > Calendar.DECEMBER) { 986 throw new IllegalArgumentException (); 987 } 988 if (endTime < 0 || endTime > TimeZone.MILLIS_PER_DAY || 989 endTimeMode < WALL_TIME || endTimeMode > UTC_TIME) { 990 throw new IllegalArgumentException (); 991 } 992 if (endDayOfWeek == 0) { 993 endMode = DOM_MODE; 994 } else { 995 if (endDayOfWeek > 0) { 996 endMode = DOW_IN_MONTH_MODE; 997 } else { 998 endDayOfWeek = (int)-endDayOfWeek; 999 if (endDay > 0) { 1000 endMode = DOW_GE_DOM_MODE; 1001 } else { 1002 endDay = (int)-endDay; 1003 endMode = DOW_LE_DOM_MODE; 1004 } 1005 } 1006 if (endDayOfWeek > Calendar.SATURDAY) { 1007 throw new IllegalArgumentException (); 1008 } 1009 } 1010 if (endMode == DOW_IN_MONTH_MODE) { 1011 if (endDay < -5 || endDay > 5) { 1012 throw new IllegalArgumentException (); 1013 } 1014 } else if (endDay<1 || endDay > staticMonthLength[endMonth]) { 1015 throw new IllegalArgumentException (); 1016 } 1017 } 1018 } 1019 1020 1026 public boolean equals(Object obj){ 1027 if (this == obj) return true; 1028 if (obj == null || getClass() != obj.getClass()) return false; 1029 SimpleTimeZone that = (SimpleTimeZone) obj; 1030 return raw == that.raw && 1031 useDaylight == that.useDaylight && 1032 idEquals(getID(),that.getID()) && 1033 (!useDaylight 1034 || (dst == that.dst && 1036 startMode == that.startMode && 1037 startMonth == that.startMonth && 1038 startDay == that.startDay && 1039 startDayOfWeek == that.startDayOfWeek && 1040 startTime == that.startTime && 1041 startTimeMode == that.startTimeMode && 1042 endMode == that.endMode && 1043 endMonth == that.endMonth && 1044 endDay == that.endDay && 1045 endDayOfWeek == that.endDayOfWeek && 1046 endTime == that.endTime && 1047 endTimeMode == that.endTimeMode && 1048 startYear == that.startYear )); 1049 1050 } 1051 private boolean idEquals(String id1, String id2){ 1052 if(id1==null && id2==null){ 1053 return true; 1054 } 1055 if(id1!=null && id2!=null){ 1056 return id1.equals(id2); 1057 } 1058 return false; 1059 } 1060 1061 1067 public int hashCode(){ 1068 int ret = (int)( super.hashCode() + 1069 raw ^ (raw>>>8) + 1070 (useDaylight?0:1)); 1071 if(!useDaylight){ 1072 ret += (int)(dst ^ (dst>>>10) + 1073 startMode ^ (startMode>>>11) + 1074 startMonth ^ (startMonth>>>12) + 1075 startDay ^ (startDay>>>13) + 1076 startDayOfWeek ^ (startDayOfWeek>>>14) + 1077 startTime ^ (startTime>>>15) + 1078 startTimeMode ^ (startTimeMode>>>16) + 1079 endMode ^ (endMode>>>17) + 1080 endMonth ^ (endMonth>>>18) + 1081 endDay ^ (endDay>>>19) + 1082 endDayOfWeek ^ (endDayOfWeek>>>20) + 1083 endTime ^ (endTime>>>21) + 1084 endTimeMode ^ (endTimeMode>>>22) + 1085 startYear ^ (startYear>>>23)); 1086 } 1087 return ret; 1088 } 1089 1090 1096 public Object clone() { 1097 SimpleTimeZone clone = new SimpleTimeZone( raw, getID()); 1098 clone.startMonth = startMonth; 1099 clone.startDay = startDay; 1100 clone.startDayOfWeek = startDayOfWeek; 1101 clone.startTime = startTime; 1102 clone.startTimeMode = startTimeMode; 1103 clone.endMonth = endMonth; 1104 clone.endDay = endDay; 1105 clone.endDayOfWeek = endDayOfWeek; 1106 clone.endTime = endTime; 1107 clone.endTimeMode = endTimeMode; 1108 clone.dst = dst; 1109 clone.startYear = startYear; 1110 clone.startMode = startMode; 1111 clone.endMode = endMode; 1112 clone.useDaylight = useDaylight; 1113 return clone; 1114 } 1115 1116 1120 public boolean hasSameRules(TimeZone othr) { 1121 if(!(othr instanceof SimpleTimeZone)){ 1122 return false; 1123 } 1124 SimpleTimeZone other = (SimpleTimeZone)othr; 1125 return other != null && 1126 raw == other.raw && 1127 useDaylight == other.useDaylight && 1128 (!useDaylight 1129 || (dst == other.dst && 1131 startMode == other.startMode && 1132 startMonth == other.startMonth && 1133 startDay == other.startDay && 1134 startDayOfWeek == other.startDayOfWeek && 1135 startTime == other.startTime && 1136 startTimeMode == other.startTimeMode && 1137 endMode == other.endMode && 1138 endMonth == other.endMonth && 1139 endDay == other.endDay && 1140 endDayOfWeek == other.endDayOfWeek && 1141 endTime == other.endTime && 1142 endTimeMode == other.endTimeMode && 1143 startYear == other.startYear)); 1144 } 1145} 1146 1147 | Popular Tags |