1 7 8 20 21 package java.util; 22 23 import java.io.IOException ; 24 import java.io.ObjectInputStream ; 25 import java.io.ObjectOutputStream ; 26 import java.io.Serializable ; 27 import java.security.AccessController ; 28 import java.security.PrivilegedExceptionAction ; 29 import java.text.DateFormat ; 30 import sun.text.resources.LocaleData; 31 import sun.util.BuddhistCalendar; 32 import sun.util.calendar.ZoneInfo; 33 34 285 public abstract class Calendar implements Serializable , Cloneable , Comparable <Calendar > { 286 287 290 300 306 316 320 330 337 345 public final static int ERA = 0; 346 347 351 public final static int YEAR = 1; 352 353 372 public final static int MONTH = 2; 373 374 385 public final static int WEEK_OF_YEAR = 3; 386 387 398 public final static int WEEK_OF_MONTH = 4; 399 400 407 public final static int DATE = 5; 408 409 416 public final static int DAY_OF_MONTH = 5; 417 418 422 public final static int DAY_OF_YEAR = 6; 423 424 438 public final static int DAY_OF_WEEK = 7; 439 440 463 public final static int DAY_OF_WEEK_IN_MONTH = 8; 464 465 474 public final static int AM_PM = 9; 475 476 485 public final static int HOUR = 10; 486 487 494 public final static int HOUR_OF_DAY = 11; 495 496 501 public final static int MINUTE = 12; 502 503 508 public final static int SECOND = 13; 509 510 515 public final static int MILLISECOND = 14; 516 517 526 public final static int ZONE_OFFSET = 15; 527 528 537 public final static int DST_OFFSET = 16; 538 539 543 public final static int FIELD_COUNT = 17; 544 545 549 public final static int SUNDAY = 1; 550 551 555 public final static int MONDAY = 2; 556 557 561 public final static int TUESDAY = 3; 562 563 567 public final static int WEDNESDAY = 4; 568 569 573 public final static int THURSDAY = 5; 574 575 579 public final static int FRIDAY = 6; 580 581 585 public final static int SATURDAY = 7; 586 587 591 public final static int JANUARY = 0; 592 593 597 public final static int FEBRUARY = 1; 598 599 603 public final static int MARCH = 2; 604 605 609 public final static int APRIL = 3; 610 611 615 public final static int MAY = 4; 616 617 621 public final static int JUNE = 5; 622 623 627 public final static int JULY = 6; 628 629 633 public final static int AUGUST = 7; 634 635 639 public final static int SEPTEMBER = 8; 640 641 645 public final static int OCTOBER = 9; 646 647 651 public final static int NOVEMBER = 10; 652 653 657 public final static int DECEMBER = 11; 658 659 664 public final static int UNDECIMBER = 12; 665 666 670 public final static int AM = 0; 671 672 676 public final static int PM = 1; 677 678 689 695 protected int fields[]; 696 697 705 protected boolean isSet[]; 706 707 712 transient private int stamp[]; 713 714 720 protected long time; 721 722 728 protected boolean isTimeSet; 729 730 737 protected boolean areFieldsSet; 738 739 743 transient boolean areAllFieldsSet; 744 745 752 private boolean lenient = true; 753 754 759 private TimeZone zone; 760 761 764 transient private boolean sharedZone = false; 765 766 771 private int firstDayOfWeek; 772 773 778 private int minimalDaysInFirstWeek; 779 780 784 private static Hashtable <Locale , int[]> cachedLocaleData = new Hashtable <Locale , int[]>(3); 785 786 790 private static final int UNSET = 0; 791 792 795 private static final int COMPUTED = 1; 796 797 802 private static final int MINIMUM_USER_STAMP = 2; 803 804 807 static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1; 808 809 816 private int nextStamp = MINIMUM_USER_STAMP; 817 818 static final int currentSerialVersion = 1; 827 828 848 private int serialVersionOnStream = currentSerialVersion; 849 850 static final long serialVersionUID = -1807547505821590642L; 852 853 final static int ERA_MASK = (1 << ERA); 855 final static int YEAR_MASK = (1 << YEAR); 856 final static int MONTH_MASK = (1 << MONTH); 857 final static int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR); 858 final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH); 859 final static int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH); 860 final static int DATE_MASK = DAY_OF_MONTH_MASK; 861 final static int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR); 862 final static int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK); 863 final static int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH); 864 final static int AM_PM_MASK = (1 << AM_PM); 865 final static int HOUR_MASK = (1 << HOUR); 866 final static int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY); 867 final static int MINUTE_MASK = (1 << MINUTE); 868 final static int SECOND_MASK = (1 << SECOND); 869 final static int MILLISECOND_MASK = (1 << MILLISECOND); 870 final static int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET); 871 final static int DST_OFFSET_MASK = (1 << DST_OFFSET); 872 873 878 protected Calendar() 879 { 880 this(TimeZone.getDefaultRef(), Locale.getDefault()); 881 sharedZone = true; 882 } 883 884 890 protected Calendar(TimeZone zone, Locale aLocale) 891 { 892 fields = new int[FIELD_COUNT]; 893 isSet = new boolean[FIELD_COUNT]; 894 stamp = new int[FIELD_COUNT]; 895 896 this.zone = zone; 897 setWeekCountData(aLocale); 898 } 899 900 907 public static Calendar getInstance() 908 { 909 Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault()); 910 cal.sharedZone = true; 911 return cal; 912 } 913 914 922 public static Calendar getInstance(TimeZone zone) 923 { 924 return createCalendar(zone, Locale.getDefault()); 925 } 926 927 935 public static Calendar getInstance(Locale aLocale) 936 { 937 Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale); 938 cal.sharedZone = true; 939 return cal; 940 } 941 942 951 public static Calendar getInstance(TimeZone zone, 952 Locale aLocale) 953 { 954 return createCalendar(zone, aLocale); 955 } 956 957 private static Calendar createCalendar(TimeZone zone, 958 Locale aLocale) 959 { 960 if ("th".equals(aLocale.getLanguage()) 963 && ("TH".equals(aLocale.getCountry()))) { 964 return new sun.util.BuddhistCalendar(zone, aLocale); 965 } 966 967 return new GregorianCalendar (zone, aLocale); 969 } 970 971 980 public static synchronized Locale [] getAvailableLocales() 981 { 982 return DateFormat.getAvailableLocales(); 983 } 984 985 993 protected abstract void computeTime(); 994 995 1005 protected abstract void computeFields(); 1006 1007 1016 public final Date getTime() { 1017 return new Date (getTimeInMillis()); 1018 } 1019 1020 1031 public final void setTime(Date date) { 1032 setTimeInMillis(date.getTime()); 1033 } 1034 1035 1042 public long getTimeInMillis() { 1043 if (!isTimeSet) { 1044 updateTime(); 1045 } 1046 return time; 1047 } 1048 1049 1056 public void setTimeInMillis(long millis) { 1057 if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet 1060 && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) { 1061 return; 1062 } 1063 time = millis; 1064 isTimeSet = true; 1065 areFieldsSet = false; 1066 computeFields(); 1067 areAllFieldsSet = areFieldsSet = true; 1068 } 1069 1070 1086 public int get(int field) 1087 { 1088 complete(); 1089 return internalGet(field); 1090 } 1091 1092 1100 protected final int internalGet(int field) 1101 { 1102 return fields[field]; 1103 } 1104 1105 1117 final void internalSet(int field, int value) 1118 { 1119 fields[field] = value; 1120 } 1121 1122 1136 public void set(int field, int value) 1137 { 1138 if (isLenient() && areFieldsSet && !areAllFieldsSet) { 1139 computeFields(); 1140 } 1141 internalSet(field, value); 1142 isTimeSet = false; 1143 areFieldsSet = false; 1144 isSet[field] = true; 1145 stamp[field] = nextStamp++; 1146 if (nextStamp == Integer.MAX_VALUE) { 1147 adjustStamp(); 1148 } 1149 } 1150 1151 1165 public final void set(int year, int month, int date) 1166 { 1167 set(YEAR, year); 1168 set(MONTH, month); 1169 set(DATE, date); 1170 } 1171 1172 1189 public final void set(int year, int month, int date, int hourOfDay, int minute) 1190 { 1191 set(YEAR, year); 1192 set(MONTH, month); 1193 set(DATE, date); 1194 set(HOUR_OF_DAY, hourOfDay); 1195 set(MINUTE, minute); 1196 } 1197 1198 1216 public final void set(int year, int month, int date, int hourOfDay, int minute, 1217 int second) 1218 { 1219 set(YEAR, year); 1220 set(MONTH, month); 1221 set(DATE, date); 1222 set(HOUR_OF_DAY, hourOfDay); 1223 set(MINUTE, minute); 1224 set(SECOND, second); 1225 } 1226 1227 1241 public final void clear() 1242 { 1243 for (int i = 0; i < fields.length; ) { 1244 stamp[i] = fields[i] = 0; isSet[i++] = false; 1246 } 1247 areAllFieldsSet = areFieldsSet = false; 1248 isTimeSet = false; 1249 } 1250 1251 1272 public final void clear(int field) 1273 { 1274 fields[field] = 0; 1275 stamp[field] = UNSET; 1276 isSet[field] = false; 1277 1278 areAllFieldsSet = areFieldsSet = false; 1279 isTimeSet = false; 1280 } 1281 1282 1290 public final boolean isSet(int field) 1291 { 1292 return stamp[field] != UNSET; 1293 } 1294 1295 1302 protected void complete() 1303 { 1304 if (!isTimeSet) 1305 updateTime(); 1306 if (!areFieldsSet || !areAllFieldsSet) { 1307 computeFields(); areAllFieldsSet = areFieldsSet = true; 1309 } else { 1310 setFieldsComputed(ALL_FIELDS); 1315 } 1316 } 1317 1318 1331 final boolean isExternallySet(int field) { 1332 return stamp[field] >= MINIMUM_USER_STAMP; 1333 } 1334 1335 1341 final int getSetStateFields() { 1342 int mask = 0; 1343 for (int i = 0; i < fields.length; i++) { 1344 if (stamp[i] != UNSET) { 1345 mask |= 1 << i; 1346 } 1347 } 1348 return mask; 1349 } 1350 1351 1364 final void setFieldsComputed(int fieldMask) { 1365 if (fieldMask == ALL_FIELDS) { 1366 for (int i = 0; i < fields.length; i++) { 1367 stamp[i] = COMPUTED; 1368 isSet[i] = true; 1369 } 1370 areFieldsSet = areAllFieldsSet = true; 1371 } else { 1372 for (int i = 0; i < fields.length; i++) { 1373 if ((fieldMask & 1) == 1) { 1374 stamp[i] = COMPUTED; 1375 isSet[i] = true; 1376 } else { 1377 if (areAllFieldsSet && !isSet[i]) { 1378 areAllFieldsSet = false; 1379 } 1380 } 1381 fieldMask >>>= 1; 1382 } 1383 } 1384 } 1385 1386 1401 final void setFieldsNormalized(int fieldMask) { 1402 if (fieldMask == ALL_FIELDS) { 1403 areFieldsSet = areAllFieldsSet = true; 1405 return; 1406 } 1407 1408 for (int i = 0; i < fields.length; i++) { 1409 if ((fieldMask & 1) == 0) { 1410 stamp[i] = fields[i] = 0; isSet[i] = false; 1412 } 1413 fieldMask >>= 1; 1414 } 1415 1416 areFieldsSet = true; 1419 areAllFieldsSet = false; 1420 } 1421 1422 1426 final boolean isPartiallyNormalized() { 1427 return areFieldsSet && !areAllFieldsSet; 1428 } 1429 1430 1434 final boolean isFullyNormalized() { 1435 return areFieldsSet && areAllFieldsSet; 1436 } 1437 1438 1441 final void setUnnormalized() { 1442 areFieldsSet = areAllFieldsSet = false; 1443 } 1444 1445 1449 static final boolean isFieldSet(int fieldMask, int field) { 1450 return (fieldMask & (1 << field)) != 0; 1451 } 1452 1453 1474 final int selectFields() { 1475 1477 int fieldMask = YEAR_MASK; 1482 1483 if (stamp[ERA] != UNSET) { 1484 fieldMask |= ERA_MASK; 1485 } 1486 int dowStamp = stamp[DAY_OF_WEEK]; 1499 int monthStamp = stamp[MONTH]; 1500 int domStamp = stamp[DAY_OF_MONTH]; 1501 int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp); 1502 int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); 1503 int doyStamp = stamp[DAY_OF_YEAR]; 1504 int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp); 1505 1506 int bestStamp = domStamp; 1507 if (womStamp > bestStamp) { 1508 bestStamp = womStamp; 1509 } 1510 if (dowimStamp > bestStamp) { 1511 bestStamp = dowimStamp; 1512 } 1513 if (doyStamp > bestStamp) { 1514 bestStamp = doyStamp; 1515 } 1516 if (woyStamp > bestStamp) { 1517 bestStamp = woyStamp; 1518 } 1519 1520 1524 if (bestStamp == UNSET) { 1525 womStamp = stamp[WEEK_OF_MONTH]; 1526 dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); 1527 woyStamp = stamp[WEEK_OF_YEAR]; 1528 bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp); 1529 1530 1534 if (bestStamp == UNSET) { 1535 bestStamp = domStamp = monthStamp; 1536 } 1537 } 1538 1539 if (bestStamp == domStamp || 1540 (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) || 1541 (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) { 1542 fieldMask |= MONTH_MASK; 1543 if (bestStamp == domStamp) { 1544 fieldMask |= DAY_OF_MONTH_MASK; 1545 } else { 1546 assert (bestStamp == womStamp || bestStamp == dowimStamp); 1547 if (dowStamp != UNSET) { 1548 fieldMask |= DAY_OF_WEEK_MASK; 1549 } 1550 if (bestStamp == womStamp) { 1551 fieldMask |= WEEK_OF_MONTH_MASK; 1552 } else { 1553 assert (bestStamp == dowimStamp); 1554 if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) { 1555 fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK; 1556 } 1557 } 1558 } 1559 } else { 1560 assert (bestStamp == doyStamp || bestStamp == woyStamp || 1561 bestStamp == UNSET); 1562 if (bestStamp == doyStamp) { 1563 fieldMask |= DAY_OF_YEAR_MASK; 1564 } else { 1565 assert (bestStamp == woyStamp); 1566 if (dowStamp != UNSET) { 1567 fieldMask |= DAY_OF_WEEK_MASK; 1568 } 1569 fieldMask |= WEEK_OF_YEAR_MASK; 1570 } 1571 } 1572 1573 int hourOfDayStamp = stamp[HOUR_OF_DAY]; 1577 int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]); 1578 bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp; 1579 1580 if (bestStamp == UNSET) { 1582 bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]); 1583 } 1584 1585 if (bestStamp != UNSET) { 1587 if (bestStamp == hourOfDayStamp) { 1588 fieldMask |= HOUR_OF_DAY_MASK; 1589 } else { 1590 fieldMask |= HOUR_MASK; 1591 if (stamp[AM_PM] != UNSET) { 1592 fieldMask |= AM_PM_MASK; 1593 } 1594 } 1595 } 1596 if (stamp[MINUTE] != UNSET) { 1597 fieldMask |= MINUTE_MASK; 1598 } 1599 if (stamp[SECOND] != UNSET) { 1600 fieldMask |= SECOND_MASK; 1601 } 1602 if (stamp[MILLISECOND] != UNSET) { 1603 fieldMask |= MILLISECOND_MASK; 1604 } 1605 if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) { 1606 fieldMask |= ZONE_OFFSET_MASK; 1607 } 1608 if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { 1609 fieldMask |= DST_OFFSET_MASK; 1610 } 1611 1612 return fieldMask; 1613 } 1614 1615 1621 private static final int aggregateStamp(int stamp_a, int stamp_b) { 1622 if (stamp_a == UNSET || stamp_b == UNSET) { 1623 return UNSET; 1624 } 1625 return (stamp_a > stamp_b) ? stamp_a : stamp_b; 1626 } 1627 1628 1650 public boolean equals(Object obj) { 1651 if (this == obj) 1652 return true; 1653 try { 1654 Calendar that = (Calendar )obj; 1655 return compareTo(getMillisOf(that)) == 0 && 1656 lenient == that.lenient && 1657 firstDayOfWeek == that.firstDayOfWeek && 1658 minimalDaysInFirstWeek == that.minimalDaysInFirstWeek && 1659 zone.equals(that.zone); 1660 } catch (Exception e) { 1661 } 1665 return false; 1666 } 1667 1668 1674 public int hashCode() { 1675 int otheritems = (lenient ? 1 : 0) 1677 | (firstDayOfWeek << 1) 1678 | (minimalDaysInFirstWeek << 4) 1679 | (zone.hashCode() << 7); 1680 long t = getMillisOf(this); 1681 return (int) t ^ (int)(t >> 32) ^ otheritems; 1682 } 1683 1684 1700 public boolean before(Object when) { 1701 return when instanceof Calendar 1702 && compareTo((Calendar )when) < 0; 1703 } 1704 1705 1721 public boolean after(Object when) { 1722 return when instanceof Calendar 1723 && compareTo((Calendar )when) > 0; 1724 } 1725 1726 1745 public int compareTo(Calendar anotherCalendar) { 1746 return compareTo(getMillisOf(anotherCalendar)); 1747 } 1748 1749 1760 abstract public void add(int field, int amount); 1761 1762 1782 abstract public void roll(int field, boolean up); 1783 1784 1803 public void roll(int field, int amount) 1804 { 1805 while (amount > 0) { 1806 roll(field, true); 1807 amount--; 1808 } 1809 while (amount < 0) { 1810 roll(field, false); 1811 amount++; 1812 } 1813 } 1814 1815 1820 public void setTimeZone(TimeZone value) 1821 { 1822 zone = value; 1823 sharedZone = false; 1824 1833 areAllFieldsSet = areFieldsSet = false; 1834 } 1835 1836 1841 public TimeZone getTimeZone() 1842 { 1843 if (sharedZone) { 1846 zone = (TimeZone ) zone.clone(); 1847 sharedZone = false; 1848 } 1849 return zone; 1850 } 1851 1852 1855 TimeZone getZone() { 1856 return zone; 1857 } 1858 1859 1862 void setZoneShared(boolean shared) { 1863 sharedZone = shared; 1864 } 1865 1866 1878 public void setLenient(boolean lenient) 1879 { 1880 this.lenient = lenient; 1881 } 1882 1883 1890 public boolean isLenient() 1891 { 1892 return lenient; 1893 } 1894 1895 1903 public void setFirstDayOfWeek(int value) 1904 { 1905 if (firstDayOfWeek == value) { 1906 return; 1907 } 1908 firstDayOfWeek = value; 1909 invalidateWeekFields(); 1910 } 1911 1912 1920 public int getFirstDayOfWeek() 1921 { 1922 return firstDayOfWeek; 1923 } 1924 1925 1935 public void setMinimalDaysInFirstWeek(int value) 1936 { 1937 if (minimalDaysInFirstWeek == value) { 1938 return; 1939 } 1940 minimalDaysInFirstWeek = value; 1941 invalidateWeekFields(); 1942 } 1943 1944 1954 public int getMinimalDaysInFirstWeek() 1955 { 1956 return minimalDaysInFirstWeek; 1957 } 1958 1959 1974 abstract public int getMinimum(int field); 1975 1976 1991 abstract public int getMaximum(int field); 1992 1993 2009 abstract public int getGreatestMinimum(int field); 2010 2011 2031 abstract public int getLeastMaximum(int field); 2032 2033 2053 public int getActualMinimum(int field) { 2054 int fieldValue = getGreatestMinimum(field); 2055 int endValue = getMinimum(field); 2056 2057 if (fieldValue == endValue) { 2059 return fieldValue; 2060 } 2061 2062 Calendar work = (Calendar )this.clone(); 2065 work.setLenient(true); 2066 2067 int result = fieldValue; 2071 2072 do { 2073 work.set(field, fieldValue); 2074 if (work.get(field) != fieldValue) { 2075 break; 2076 } else { 2077 result = fieldValue; 2078 fieldValue--; 2079 } 2080 } while (fieldValue >= endValue); 2081 2082 return result; 2083 } 2084 2085 2107 public int getActualMaximum(int field) { 2108 int fieldValue = getLeastMaximum(field); 2109 int endValue = getMaximum(field); 2110 2111 if (fieldValue == endValue) { 2113 return fieldValue; 2114 } 2115 2116 Calendar work = (Calendar )this.clone(); 2119 work.setLenient(true); 2120 2121 if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH) 2124 work.set(DAY_OF_WEEK, firstDayOfWeek); 2125 2126 int result = fieldValue; 2130 2131 do { 2132 work.set(field, fieldValue); 2133 if (work.get(field) != fieldValue) { 2134 break; 2135 } else { 2136 result = fieldValue; 2137 fieldValue++; 2138 } 2139 } while (fieldValue <= endValue); 2140 2141 return result; 2142 } 2143 2144 2149 public Object clone() 2150 { 2151 try { 2152 Calendar other = (Calendar ) super.clone(); 2153 2154 other.fields = new int[FIELD_COUNT]; 2155 other.isSet = new boolean[FIELD_COUNT]; 2156 other.stamp = new int[FIELD_COUNT]; 2157 for (int i = 0; i < FIELD_COUNT; i++) { 2158 other.fields[i] = fields[i]; 2159 other.stamp[i] = stamp[i]; 2160 other.isSet[i] = isSet[i]; 2161 } 2162 other.zone = (TimeZone ) zone.clone(); 2163 return other; 2164 } 2165 catch (CloneNotSupportedException e) { 2166 throw new InternalError (); 2168 } 2169 } 2170 2171 private static final String [] FIELD_NAME = { 2172 "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", 2173 "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", 2174 "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", 2175 "DST_OFFSET" 2176 }; 2177 2178 2186 static final String getFieldName(int field) { 2187 return FIELD_NAME[field]; 2188 } 2189 2190 2198 public String toString() { 2199 StringBuilder buffer = new StringBuilder (800); 2204 buffer.append(getClass().getName()).append('['); 2205 appendValue(buffer, "time", isTimeSet, time); 2206 buffer.append(",areFieldsSet=").append(areFieldsSet); 2207 buffer.append(",areAllFieldsSet=").append(areAllFieldsSet); 2208 buffer.append(",lenient=").append(lenient); 2209 buffer.append(",zone=").append(zone); 2210 appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek); 2211 appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek); 2212 for (int i = 0; i < FIELD_COUNT; ++i) { 2213 buffer.append(','); 2214 appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]); 2215 } 2216 buffer.append(']'); 2217 return buffer.toString(); 2218 } 2219 2220 2222 private static final void appendValue(StringBuilder sb, String item, boolean valid, long value) { 2223 sb.append(item).append('='); 2224 if (valid) { 2225 sb.append(value); 2226 } else { 2227 sb.append('?'); 2228 } 2229 } 2230 2231 2237 private void setWeekCountData(Locale desiredLocale) 2238 { 2239 2240 int[] data = cachedLocaleData.get(desiredLocale); 2241 if (data == null) { 2242 ResourceBundle resource = LocaleData.getLocaleElements(desiredLocale); 2243 String [] dateTimePatterns = 2244 resource.getStringArray("DateTimeElements"); 2245 data = new int[2]; 2246 data[0] = Integer.parseInt(dateTimePatterns[0]); 2247 data[1] = Integer.parseInt(dateTimePatterns[1]); 2248 cachedLocaleData.put(desiredLocale, data); 2249 } 2250 firstDayOfWeek = data[0]; 2251 minimalDaysInFirstWeek = data[1]; 2252 } 2253 2254 2259 private void updateTime() { 2260 computeTime(); 2261 isTimeSet = true; 2264 } 2265 2266 private int compareTo(long t) { 2267 long thisTime = getMillisOf(this); 2268 return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1; 2269 } 2270 2271 private static final long getMillisOf(Calendar calendar) { 2272 if (calendar.isTimeSet) { 2273 return calendar.time; 2274 } 2275 Calendar cal = (Calendar ) calendar.clone(); 2276 cal.setLenient(true); 2277 return cal.getTimeInMillis(); 2278 } 2279 2280 2284 private final void adjustStamp() { 2285 int max = MINIMUM_USER_STAMP; 2286 int newStamp = MINIMUM_USER_STAMP; 2287 2288 for (;;) { 2289 int min = Integer.MAX_VALUE; 2290 for (int i = 0; i < stamp.length; i++) { 2291 int v = stamp[i]; 2292 if (v >= newStamp && min > v) { 2293 min = v; 2294 } 2295 if (max < v) { 2296 max = v; 2297 } 2298 } 2299 if (max != min && min == Integer.MAX_VALUE) { 2300 break; 2301 } 2302 for (int i = 0; i < stamp.length; i++) { 2303 if (stamp[i] == min) { 2304 stamp[i] = newStamp; 2305 } 2306 } 2307 newStamp++; 2308 if (min == max) { 2309 break; 2310 } 2311 } 2312 nextStamp = newStamp; 2313 } 2314 2315 2319 private void invalidateWeekFields() 2320 { 2321 if (stamp[WEEK_OF_MONTH] != COMPUTED && 2322 stamp[WEEK_OF_YEAR] != COMPUTED) { 2323 return; 2324 } 2325 2326 Calendar cal = (Calendar ) clone(); 2330 cal.setLenient(true); 2331 cal.clear(WEEK_OF_MONTH); 2332 cal.clear(WEEK_OF_YEAR); 2333 2334 if (stamp[WEEK_OF_MONTH] == COMPUTED) { 2335 int weekOfMonth = cal.get(WEEK_OF_MONTH); 2336 if (fields[WEEK_OF_MONTH] != weekOfMonth) { 2337 fields[WEEK_OF_MONTH] = weekOfMonth; 2338 } 2339 } 2340 2341 if (stamp[WEEK_OF_YEAR] == COMPUTED) { 2342 int weekOfYear = cal.get(WEEK_OF_YEAR); 2343 if (fields[WEEK_OF_YEAR] != weekOfYear) { 2344 fields[WEEK_OF_YEAR] = weekOfYear; 2345 } 2346 } 2347 } 2348 2349 2362 private void writeObject(ObjectOutputStream stream) 2363 throws IOException 2364 { 2365 if (!isTimeSet) { 2368 try { 2369 updateTime(); 2370 } 2371 catch (IllegalArgumentException e) {} 2372 } 2373 2374 TimeZone savedZone = null; 2378 if (zone instanceof ZoneInfo) { 2379 SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance(); 2380 if (stz == null) { 2381 stz = new SimpleTimeZone (zone.getRawOffset(), zone.getID()); 2382 } 2383 savedZone = zone; 2384 zone = stz; 2385 } 2386 2387 stream.defaultWriteObject(); 2389 2390 stream.writeObject(savedZone); 2394 if (savedZone != null) { 2395 zone = savedZone; 2396 } 2397 } 2398 2399 2402 private void readObject(ObjectInputStream stream) 2403 throws IOException , ClassNotFoundException 2404 { 2405 final ObjectInputStream input = stream; 2406 input.defaultReadObject(); 2407 2408 stamp = new int[FIELD_COUNT]; 2409 2410 if (serialVersionOnStream >= 2) 2414 { 2415 isTimeSet = true; 2416 if (fields == null) fields = new int[FIELD_COUNT]; 2417 if (isSet == null) isSet = new boolean[FIELD_COUNT]; 2418 } 2419 else if (serialVersionOnStream >= 0) 2420 { 2421 for (int i=0; i<FIELD_COUNT; ++i) 2422 stamp[i] = isSet[i] ? COMPUTED : UNSET; 2423 } 2424 2425 serialVersionOnStream = currentSerialVersion; 2426 2427 try { 2429 ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged( 2430 new PrivilegedExceptionAction () { 2431 public Object run() throws Exception { 2432 return input.readObject(); 2433 } 2434 }); 2435 if (zi != null) { 2436 zone = zi; 2437 } 2438 } catch (Exception e) { 2439 } 2440 2441 if (zone instanceof SimpleTimeZone ) { 2446 String id = zone.getID(); 2447 TimeZone zi = TimeZone.getTimeZone(id); 2448 if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) { 2449 zone = zi; 2450 } 2451 } 2452 } 2453} 2454 | Popular Tags |