| 1 7 8 20 21 package java.util; 22 23 import java.io.ObjectInputStream ; 24 import java.io.ObjectOutputStream ; 25 import java.io.IOException ; 26 import sun.util.calendar.CalendarSystem; 27 import sun.util.calendar.CalendarUtils; 28 import sun.util.calendar.BaseCalendar; 29 import sun.util.calendar.Gregorian; 30 31 132 133 public class SimpleTimeZone extends TimeZone { 134 141 public SimpleTimeZone(int rawOffset, String ID) 142 { 143 this.rawOffset = rawOffset; 144 setID (ID); 145 dstSavings = millisPerHour; } 147 148 197 public SimpleTimeZone(int rawOffset, String ID, 198 int startMonth, int startDay, int startDayOfWeek, int startTime, 199 int endMonth, int endDay, int endDayOfWeek, int endTime) 200 { 201 this(rawOffset, ID, 202 startMonth, startDay, startDayOfWeek, startTime, WALL_TIME, 203 endMonth, endDay, endDayOfWeek, endTime, WALL_TIME, 204 millisPerHour); 205 } 206 207 255 public SimpleTimeZone(int rawOffset, String ID, 256 int startMonth, int startDay, int startDayOfWeek, int startTime, 257 int endMonth, int endDay, int endDayOfWeek, int endTime, 258 int dstSavings) 259 { 260 this(rawOffset, ID, 261 startMonth, startDay, startDayOfWeek, startTime, WALL_TIME, 262 endMonth, endDay, endDayOfWeek, endTime, WALL_TIME, 263 dstSavings); 264 } 265 266 311 public SimpleTimeZone(int rawOffset, String ID, 312 int startMonth, int startDay, int startDayOfWeek, 313 int startTime, int startTimeMode, 314 int endMonth, int endDay, int endDayOfWeek, 315 int endTime, int endTimeMode, 316 int dstSavings) { 317 318 setID(ID); 319 this.rawOffset = rawOffset; 320 this.startMonth = startMonth; 321 this.startDay = startDay; 322 this.startDayOfWeek = startDayOfWeek; 323 this.startTime = startTime; 324 this.startTimeMode = startTimeMode; 325 this.endMonth = endMonth; 326 this.endDay = endDay; 327 this.endDayOfWeek = endDayOfWeek; 328 this.endTime = endTime; 329 this.endTimeMode = endTimeMode; 330 this.dstSavings = dstSavings; 331 332 decodeRules(); 334 if (dstSavings <= 0) { 335 throw new IllegalArgumentException ("Illegal daylight saving value: " + dstSavings); 336 } 337 } 338 339 344 public void setStartYear(int year) 345 { 346 startYear = year; 347 invalidateCache(); 348 } 349 350 368 public void setStartRule(int startMonth, int startDay, int startDayOfWeek, int startTime) 369 { 370 this.startMonth = startMonth; 371 this.startDay = startDay; 372 this.startDayOfWeek = startDayOfWeek; 373 this.startTime = startTime; 374 startTimeMode = WALL_TIME; 375 decodeStartRule(); 376 invalidateCache(); 377 } 378 379 395 public void setStartRule(int startMonth, int startDay, int startTime) { 396 setStartRule(startMonth, startDay, 0, startTime); 397 } 398 399 418 public void setStartRule(int startMonth, int startDay, int startDayOfWeek, 419 int startTime, boolean after) 420 { 421 if (after) { 423 setStartRule(startMonth, startDay, -startDayOfWeek, startTime); 424 } else { 425 setStartRule(startMonth, -startDay, -startDayOfWeek, startTime); 426 } 427 } 428 429 448 public void setEndRule(int endMonth, int endDay, int endDayOfWeek, 449 int endTime) 450 { 451 this.endMonth = endMonth; 452 this.endDay = endDay; 453 this.endDayOfWeek = endDayOfWeek; 454 this.endTime = endTime; 455 this.endTimeMode = WALL_TIME; 456 decodeEndRule(); 457 invalidateCache(); 458 } 459 460 476 public void setEndRule(int endMonth, int endDay, int endTime) 477 { 478 setEndRule(endMonth, endDay, 0, endTime); 479 } 480 481 501 public void setEndRule(int endMonth, int endDay, int endDayOfWeek, int endTime, boolean after) 502 { 503 if (after) { 504 setEndRule(endMonth, endDay, -endDayOfWeek, endTime); 505 } else { 506 setEndRule(endMonth, -endDay, -endDayOfWeek, endTime); 507 } 508 } 509 510 521 public int getOffset(long date) { 522 return getOffsets(date, null); 523 } 524 525 528 int getOffsets(long date, int[] offsets) { 529 int offset = rawOffset; 530 531 computeOffset: 532 if (useDaylight) { 533 synchronized (this) { 534 if (cacheStart != 0) { 535 if (date >= cacheStart && date < cacheEnd) { 536 offset += dstSavings; 537 break computeOffset; 538 } 539 } 540 } 541 BaseCalendar cal = date >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER ? 542 gcal : (BaseCalendar) CalendarSystem.forName("julian"); 543 BaseCalendar.Date cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE); 544 cal.getCalendarDate(date + rawOffset, cdate); 546 int year = cdate.getNormalizedYear(); 547 if (year >= startYear) { 548 cdate.setTimeOfDay(0, 0, 0, 0); 550 offset = getOffset(cal, cdate, year, date); 551 } 552 } 553 554 if (offsets != null) { 555 offsets[0] = rawOffset; 556 offsets[1] = offset - rawOffset; 557 } 558 return offset; 559 } 560 561 587 public int getOffset(int era, int year, int month, int day, int dayOfWeek, 588 int millis) 589 { 590 if (era != GregorianCalendar.AD && era != GregorianCalendar.BC) { 591 throw new IllegalArgumentException ("Illegal era " + era); 592 } 593 594 int y = year; 595 if (era == GregorianCalendar.BC) { 596 y = 1 - y; 598 } 599 600 if (y >= 292278994) { 606 y = 2800 + y % 2800; 607 } else if (y <= -292269054) { 608 y = (int) CalendarUtils.mod((long) y, 28); 612 } 613 614 int m = month + 1; 616 617 BaseCalendar cal = gcal; 619 BaseCalendar.Date cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE); 620 cdate.setDate(y, m, day); 621 long time = cal.getTime(cdate); time += millis - rawOffset; 624 if (time < GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER) { 631 cal = (BaseCalendar) CalendarSystem.forName("julian"); 632 cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE); 633 cdate.setNormalizedDate(y, m, day); 634 time = cal.getTime(cdate) + millis - rawOffset; 635 } 636 637 if ((cdate.getNormalizedYear() != y) 638 || (cdate.getMonth() != m) 639 || (cdate.getDayOfMonth() != day) 640 || (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) 644 || (millis < 0 || millis >= (24*60*60*1000))) { 645 throw new IllegalArgumentException (); 646 } 647 648 if (!useDaylight || year < startYear || era != GregorianCalendar.CE) { 649 return rawOffset; 650 } 651 652 return getOffset(cal, cdate, y, time); 653 } 654 655 private int getOffset(BaseCalendar cal, BaseCalendar.Date cdate, int year, long time) { 656 synchronized (this) { 657 if (cacheStart != 0) { 658 if (time >= cacheStart && time < cacheEnd) { 659 return rawOffset + dstSavings; 660 } 661 if (year == cacheYear) { 662 return rawOffset; 663 } 664 } 665 } 666 667 long start = getStart(cal, cdate, year); 668 long end = getEnd(cal, cdate, year); 669 int offset = rawOffset; 670 if (start <= end) { 671 if (time >= start && time < end) { 672 offset += dstSavings; 673 } 674 synchronized (this) { 675 cacheYear = year; 676 cacheStart = start; 677 cacheEnd = end; 678 } 679 } else { 680 if (time < end) { 681 start = getStart(cal, cdate, year - 1); 684 if (time >= start) { 685 offset += dstSavings; 686 } 687 } else if (time >= start) { 688 end = getEnd(cal, cdate, year + 1); 691 if (time < end) { 692 offset += dstSavings; 693 } 694 } 695 if (start <= end) { 696 synchronized (this) { 697 cacheYear = (long) startYear - 1; 699 cacheStart = start; 700 cacheEnd = end; 701 } 702 } 703 } 704 return offset; 705 } 706 707 private long getStart(BaseCalendar cal, BaseCalendar.Date cdate, int year) { 708 int time = startTime; 709 if (startTimeMode != UTC_TIME) { 710 time -= rawOffset; 711 } 712 return getTransition(cal, cdate, startMode, year, startMonth, startDay, 713 startDayOfWeek, time); 714 } 715 716 private long getEnd(BaseCalendar cal, BaseCalendar.Date cdate, int year) { 717 int time = endTime; 718 if (startTimeMode != UTC_TIME) { 719 time -= rawOffset; 720 } 721 if (startTimeMode == WALL_TIME) { 722 time -= dstSavings; 723 } 724 return getTransition(cal, cdate, endMode, year, endMonth, endDay, 725 endDayOfWeek, time); 726 } 727 728 private long getTransition(BaseCalendar cal, BaseCalendar.Date cdate, 729 int mode, int year, int month, int dayOfMonth, 730 int dayOfWeek, int timeOfDay) { 731 cdate.setNormalizedYear(year); 732 cdate.setMonth(month + 1); 733 switch (mode) { 734 case DOM_MODE: 735 cdate.setDayOfMonth(dayOfMonth); 736 break; 737 738 case DOW_IN_MONTH_MODE: 739 cdate.setDayOfMonth(1); 740 if (dayOfMonth < 0) { 741 cdate.setDayOfMonth(cal.getMonthLength(cdate)); 742 } 743 cdate = (BaseCalendar.Date) cal.getNthDayOfWeek(dayOfMonth, dayOfWeek, cdate); 744 break; 745 746 case DOW_GE_DOM_MODE: 747 cdate.setDayOfMonth(dayOfMonth); 748 cdate = (BaseCalendar.Date) cal.getNthDayOfWeek(1, dayOfWeek, cdate); 749 break; 750 751 case DOW_LE_DOM_MODE: 752 cdate.setDayOfMonth(dayOfMonth); 753 cdate = (BaseCalendar.Date) cal.getNthDayOfWeek(-1, dayOfWeek, cdate); 754 break; 755 } 756 return cal.getTime(cdate) + timeOfDay; 757 } 758 759 764 public int getRawOffset() 765 { 766 return rawOffset; 769 } 770 771 776 public void setRawOffset(int offsetMillis) 777 { 778 this.rawOffset = offsetMillis; 779 } 780 781 790 public void setDSTSavings(int millisSavedDuringDST) { 791 if (millisSavedDuringDST <= 0) { 792 throw new IllegalArgumentException ("Illegal daylight saving value: " 793 + millisSavedDuringDST); 794 } 795 dstSavings = millisSavedDuringDST; 796 } 797 798 810 public int getDSTSavings() { 811 if (useDaylight) { 812 return dstSavings; 813 } 814 return 0; 815 } 816 817 822 public boolean useDaylightTime() 823 { 824 return useDaylight; 825 } 826 827 832 public boolean inDaylightTime(Date date) 833 { 834 return (getOffset(date.getTime()) != rawOffset); 835 } 836 837 841 public Object clone() 842 { 843 return super.clone(); 844 } 845 846 850 public synchronized int hashCode() 851 { 852 return startMonth ^ startDay ^ startDayOfWeek ^ startTime ^ 853 endMonth ^ endDay ^ endDayOfWeek ^ endTime ^ rawOffset; 854 } 855 856 863 public boolean equals(Object obj) 864 { 865 if (this == obj) { 866 return true; 867 } 868 if (!(obj instanceof SimpleTimeZone )) { 869 return false; 870 } 871 872 SimpleTimeZone that = (SimpleTimeZone ) obj; 873 874 return getID().equals(that.getID()) && 875 hasSameRules(that); 876 } 877 878 885 public boolean hasSameRules(TimeZone other) { 886 if (this == other) { 887 return true; 888 } 889 if (!(other instanceof SimpleTimeZone )) { 890 return false; 891 } 892 SimpleTimeZone that = (SimpleTimeZone ) other; 893 return rawOffset == that.rawOffset && 894 useDaylight == that.useDaylight && 895 (!useDaylight 896 || (dstSavings == that.dstSavings && 898 startMode == that.startMode && 899 startMonth == that.startMonth && 900 startDay == that.startDay && 901 startDayOfWeek == that.startDayOfWeek && 902 startTime == that.startTime && 903 startTimeMode == that.startTimeMode && 904 endMode == that.endMode && 905 endMonth == that.endMonth && 906 endDay == that.endDay && 907 endDayOfWeek == that.endDayOfWeek && 908 endTime == that.endTime && 909 endTimeMode == that.endTimeMode && 910 startYear == that.startYear)); 911 } 912 913 917 public String toString() { 918 return getClass().getName() + 919 "[id=" + getID() + 920 ",offset=" + rawOffset + 921 ",dstSavings=" + dstSavings + 922 ",useDaylight=" + useDaylight + 923 ",startYear=" + startYear + 924 ",startMode=" + startMode + 925 ",startMonth=" + startMonth + 926 ",startDay=" + startDay + 927 ",startDayOfWeek=" + startDayOfWeek + 928 ",startTime=" + startTime + 929 ",startTimeMode=" + startTimeMode + 930 ",endMode=" + endMode + 931 ",endMonth=" + endMonth + 932 ",endDay=" + endDay + 933 ",endDayOfWeek=" + endDayOfWeek + 934 ",endTime=" + endTime + 935 ",endTimeMode=" + endTimeMode + ']'; 936 } 937 938 940 948 private int startMonth; 949 950 |