1 3 9 10 package com.sun.org.apache.xerces.internal.jaxp.datatype; 11 12 import java.io.Serializable ; 13 import java.math.BigDecimal ; 14 import java.math.BigInteger ; 15 import java.util.TimeZone ; 16 import java.util.SimpleTimeZone ; 17 import java.util.Calendar ; 18 import java.util.GregorianCalendar ; 19 import java.util.Date ; 20 import java.util.Locale ; 21 22 import javax.xml.XMLConstants ; 23 import javax.xml.datatype.DatatypeConstants ; 24 import javax.xml.datatype.Duration ; 25 import javax.xml.datatype.XMLGregorianCalendar ; 26 import javax.xml.namespace.QName ; 27 import com.sun.org.apache.xerces.internal.util.DatatypeMessageFormatter; 28 29 30 174 175 public class XMLGregorianCalendarImpl 176 extends XMLGregorianCalendar 177 implements Serializable , Cloneable { 178 179 182 private BigInteger eon = null; 183 184 187 private int year = DatatypeConstants.FIELD_UNDEFINED; 188 189 192 private int month = DatatypeConstants.FIELD_UNDEFINED; 193 194 197 private int day = DatatypeConstants.FIELD_UNDEFINED; 198 199 202 private int timezone = DatatypeConstants.FIELD_UNDEFINED; 203 204 207 private int hour = DatatypeConstants.FIELD_UNDEFINED; 208 209 212 private int minute = DatatypeConstants.FIELD_UNDEFINED; 213 214 217 private int second = DatatypeConstants.FIELD_UNDEFINED ; 218 219 222 private BigDecimal fractionalSecond = null; 223 224 227 private static final BigInteger BILLION = new BigInteger ("1000000000"); 228 229 233 private static final Date PURE_GREGORIAN_CHANGE = 234 new Date (Long.MIN_VALUE); 235 236 239 private static final int YEAR = 0; 240 241 244 private static final int MONTH = 1; 245 246 249 private static final int DAY = 2; 250 251 254 private static final int HOUR = 3; 255 256 259 private static final int MINUTE = 4; 260 261 264 private static final int SECOND = 5; 265 266 269 private static final int MILLISECOND = 6; 270 271 274 private static final int TIMEZONE = 7; 275 276 279 private static final int MIN_FIELD_VALUE[] = { 280 Integer.MIN_VALUE, DatatypeConstants.JANUARY, 283 1, 0, 0, 0, 0, -14 * 60 }; 290 291 294 private static final int MAX_FIELD_VALUE[] = { 295 Integer.MAX_VALUE, DatatypeConstants.DECEMBER, 298 31, 23, 59, 60, 999, 14 * 60 }; 305 306 309 private static final String FIELD_NAME[] = { 310 "Year", 311 "Month", 312 "Day", 313 "Hour", 314 "Minute", 315 "Second", 316 "Millisecond", 317 "Timezone" 318 }; 319 320 326 private static final long serialVersionUID = 1L; 327 328 340 public static final XMLGregorianCalendar LEAP_YEAR_DEFAULT = 341 createDateTime( 342 400, DatatypeConstants.JANUARY, 1, 0, 0, 0, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED ); 351 352 354 371 protected XMLGregorianCalendarImpl(String lexicalRepresentation) 372 throws IllegalArgumentException { 373 374 String format = null; 376 String lexRep = lexicalRepresentation; 377 final int NOT_FOUND = -1; 378 int lexRepLength = lexRep.length(); 379 380 381 if (lexRep.indexOf('T') != NOT_FOUND) { 385 format = "%Y-%M-%DT%h:%m:%s" + "%z"; 387 } else if (lexRepLength >= 3 && lexRep.charAt(2) == ':') { 388 format = "%h:%m:%s" +"%z"; 390 } else if (lexRep.startsWith("--")) { 391 if (lexRepLength >= 3 && lexRep.charAt(2) == '-') { 393 format = "---%D" + "%z"; 396 } else if (lexRepLength >= 6 && 397 lexRep.charAt(5) == '-' && lexRep.charAt(4) == '-') { 398 format = "--%M--%z"; 401 } else { 402 format = "--%M-%D" + "%z"; 404 } 405 } else { 406 int countSeparator = 0; 408 409 411 412 int timezoneOffset = lexRep.indexOf(':'); 413 if (timezoneOffset != NOT_FOUND) { 414 415 lexRepLength -= 6; 420 } 421 422 for (int i=1; i < lexRepLength; i++) { 423 if (lexRep.charAt(i) == '-') { 424 countSeparator++; 425 } 426 } 427 if (countSeparator == 0) { 428 format = "%Y" + "%z"; 430 } else if (countSeparator == 1) { 431 format = "%Y-%M" + "%z"; 433 } else { 434 format = "%Y-%M-%D" + "%z"; 437 } 438 } 439 Parser p = new Parser(format, lexRep); 440 p.parse(); 441 442 if (!isValid()) { 444 throw new IllegalArgumentException ( 445 DatatypeMessageFormatter.formatMessage(null,"InvalidXGCRepresentation", new Object []{lexicalRepresentation}) 446 ); 448 } 449 } 450 451 455 public XMLGregorianCalendarImpl() { 456 457 } 459 460 477 protected XMLGregorianCalendarImpl( 478 BigInteger year, 479 int month, 480 int day, 481 int hour, 482 int minute, 483 int second, 484 BigDecimal fractionalSecond, 485 int timezone) { 486 487 setYear(year); 488 setMonth(month); 489 setDay(day); 490 setTime(hour, minute, second, fractionalSecond); 491 setTimezone(timezone); 492 493 if (!isValid()) { 495 496 throw new IllegalArgumentException ( 497 DatatypeMessageFormatter.formatMessage(null, 498 "InvalidXGCValue-fractional", 499 new Object [] { year, new Integer (month), new Integer (day), 500 new Integer (hour), new Integer (minute), new Integer (second), 501 fractionalSecond, new Integer (timezone)}) 502 ); 503 504 526 527 } 528 529 } 530 531 548 private XMLGregorianCalendarImpl( 549 int year, 550 int month, 551 int day, 552 int hour, 553 int minute, 554 int second, 555 int millisecond, 556 int timezone) { 557 558 setYear(year); 559 setMonth(month); 560 setDay(day); 561 setTime(hour, minute, second); 562 setTimezone(timezone); 563 setMillisecond(millisecond); 564 565 if (!isValid()) { 566 567 throw new IllegalArgumentException ( 568 DatatypeMessageFormatter.formatMessage(null, 569 "InvalidXGCValue-milli", 570 new Object [] { new Integer (year), new Integer (month), new Integer (day), 571 new Integer (hour), new Integer (minute), new Integer (second), 572 new Integer (millisecond), new Integer (timezone)}) 573 ); 574 587 588 } 589 } 590 591 648 public XMLGregorianCalendarImpl(GregorianCalendar cal) { 649 650 int year = cal.get(Calendar.YEAR); 651 if (cal.get(Calendar.ERA) == GregorianCalendar.BC) { 652 year = -year; 653 } 654 this.setYear(year); 655 656 this.setMonth(cal.get(Calendar.MONTH) + 1); 659 this.setDay(cal.get(Calendar.DAY_OF_MONTH)); 660 this.setTime( 661 cal.get(Calendar.HOUR_OF_DAY), 662 cal.get(Calendar.MINUTE), 663 cal.get(Calendar.SECOND), 664 cal.get(Calendar.MILLISECOND)); 665 666 int offsetInMinutes = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000); 668 this.setTimezone(offsetInMinutes); 669 } 670 671 673 694 public static XMLGregorianCalendar createDateTime( 695 BigInteger year, 696 int month, 697 int day, 698 int hours, 699 int minutes, 700 int seconds, 701 BigDecimal fractionalSecond, 702 int timezone) { 703 704 return new XMLGregorianCalendarImpl( 705 year, 706 month, 707 day, 708 hours, 709 minutes, 710 seconds, 711 fractionalSecond, 712 timezone); 713 } 714 715 732 public static XMLGregorianCalendar createDateTime( 733 int year, 734 int month, 735 int day, 736 int hour, 737 int minute, 738 int second) { 739 740 return new XMLGregorianCalendarImpl( 741 year, 742 month, 743 day, 744 hour, 745 minute, 746 second, 747 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED ); 750 } 751 752 772 public static XMLGregorianCalendar createDateTime( 773 int year, 774 int month, 775 int day, 776 int hours, 777 int minutes, 778 int seconds, 779 int milliseconds, 780 int timezone) { 781 782 return new XMLGregorianCalendarImpl( 783 year, 784 month, 785 day, 786 hours, 787 minutes, 788 seconds, 789 milliseconds, 790 timezone); 791 } 792 793 813 public static XMLGregorianCalendar createDate( 814 int year, 815 int month, 816 int day, 817 int timezone) { 818 819 return new XMLGregorianCalendarImpl( 820 year, 821 month, 822 day, 823 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, timezone); 828 } 829 830 845 public static XMLGregorianCalendar createTime( 846 int hours, 847 int minutes, 848 int seconds, 849 int timezone) { 850 851 return new XMLGregorianCalendarImpl( 852 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, hours, 856 minutes, 857 seconds, 858 DatatypeConstants.FIELD_UNDEFINED, timezone); 860 } 861 862 879 public static XMLGregorianCalendar createTime( 880 int hours, 881 int minutes, 882 int seconds, 883 BigDecimal fractionalSecond, 884 int timezone) { 885 886 return new XMLGregorianCalendarImpl( 887 null, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, hours, 891 minutes, 892 seconds, 893 fractionalSecond, 894 timezone); 895 } 896 897 914 public static XMLGregorianCalendar createTime( 915 int hours, 916 int minutes, 917 int seconds, 918 int milliseconds, 919 int timezone) { 920 921 return new XMLGregorianCalendarImpl( 922 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, hours, 926 minutes, 927 seconds, 928 milliseconds, 929 timezone); 930 } 931 932 934 947 public BigInteger getEon() { 948 return eon; 949 } 950 951 963 public int getYear() { 964 return year; 965 } 966 967 982 public BigInteger getEonAndYear() { 983 984 if (year != DatatypeConstants.FIELD_UNDEFINED 986 && eon != null) { 987 988 return eon.add(BigInteger.valueOf((long) year)); 989 } 990 991 if (year != DatatypeConstants.FIELD_UNDEFINED 993 && eon == null) { 994 995 return BigInteger.valueOf((long) year); 996 } 997 998 return null; 1001 } 1002 1003 1012 public int getMonth() { 1013 return month; 1014 } 1015 1016 1024 public int getDay() { 1025 return day; 1026 } 1027 1028 1037 public int getTimezone() { 1038 return timezone; 1039 } 1040 1041 1049 public int getHour() { 1050 return hour; 1051 } 1052 1053 1061 public int getMinute() { 1062 return minute; 1063 } 1064 1065 1083 public int getSecond() { 1084 return second; 1085 } 1086 1087 1090 private BigDecimal getSeconds() { 1091 1092 if (second == DatatypeConstants.FIELD_UNDEFINED) { 1093 return DECIMAL_ZERO; 1094 } 1095 BigDecimal result = BigDecimal.valueOf((long)second); 1096 if (fractionalSecond != null){ 1097 return result.add(fractionalSecond); 1098 } else { 1099 return result; 1100 } 1101 } 1102 1103 1104 1123 public int getMillisecond() { 1124 if (fractionalSecond == null) { 1125 return DatatypeConstants.FIELD_UNDEFINED; 1126 } else { 1127 return fractionalSecond.movePointRight(3).intValue(); 1131 } 1132 } 1133 1134 1151 public BigDecimal getFractionalSecond() { 1152 return fractionalSecond; 1153 } 1154 1155 1157 1168 public void setYear(BigInteger year) { 1169 if (year == null) { 1170 this.eon = null; 1171 this.year = DatatypeConstants.FIELD_UNDEFINED; 1172 } else { 1173 BigInteger temp = year.remainder(BILLION); 1174 this.year = temp.intValue(); 1175 setEon(year.subtract(temp)); 1176 } 1177 } 1178 1179 1192 public void setYear(int year) { 1193 if (year == DatatypeConstants.FIELD_UNDEFINED) { 1194 this.year = DatatypeConstants.FIELD_UNDEFINED; 1195 this.eon = null; 1196 } else if (Math.abs(year) < BILLION.intValue()) { 1197 this.year = year; 1198 this.eon = null; 1199 } else { 1200 BigInteger theYear = BigInteger.valueOf((long) year); 1201 BigInteger remainder = theYear.remainder(BILLION); 1202 this.year = remainder.intValue(); 1203 setEon(theYear.subtract(remainder)); 1204 } 1205 } 1206 1207 1215 private void setEon(BigInteger eon) { 1216 if (eon != null && eon.compareTo(BigInteger.ZERO) == 0) { 1217 this.eon = null; 1219 } else { 1220 this.eon = eon; 1221 } 1222 } 1223 1224 1235 public void setMonth(int month) { 1236 checkFieldValueConstraint(MONTH, month); 1237 this.month = month; 1238 } 1239 1240 1251 public void setDay(int day) { 1252 checkFieldValueConstraint(DAY, day); 1253 this.day = day; 1254 } 1255 1256 1268 public void setTimezone(int offset) { 1269 checkFieldValueConstraint(TIMEZONE, offset); 1270 this.timezone = offset; 1271 } 1272 1273 1289 public void setTime(int hour, int minute, int second) { 1290 setTime(hour, minute, second, null); 1291 } 1292 1293 private void checkFieldValueConstraint(int field, int value) 1294 throws IllegalArgumentException 1295 { 1296 if ((value < MIN_FIELD_VALUE[field] && value != DatatypeConstants.FIELD_UNDEFINED) || 1297 value > MAX_FIELD_VALUE[field]) { 1298 1303 throw new IllegalArgumentException ( 1304 DatatypeMessageFormatter.formatMessage(null, "InvalidFieldValue", new Object []{ new Integer (value), FIELD_NAME[field]}) 1305 ); 1306 } 1307 } 1308 1309 public void setHour(int hour) { 1310 checkFieldValueConstraint(HOUR, hour); 1311 this.hour = hour; 1312 } 1313 1314 public void setMinute(int minute) { 1315 checkFieldValueConstraint(MINUTE, minute); 1316 this.minute = minute; 1317 } 1318 1319 public void setSecond(int second) { 1320 checkFieldValueConstraint(SECOND, second); 1321 this.second = second; 1322 } 1323 1324 1341 public void setTime( 1342 int hour, 1343 int minute, 1344 int second, 1345 BigDecimal fractional) { 1346 setHour(hour); 1347 setMinute(minute); 1348 setSecond(second); 1349 setFractionalSecond(fractional); 1350 } 1351 1352 1353 1369 public void setTime(int hour, int minute, int second, int millisecond) { 1370 setHour(hour); 1371 setMinute(minute); 1372 setSecond(second); 1373 setMillisecond(millisecond); 1374 } 1375 1376 1398 public int compare(XMLGregorianCalendar rhs) { 1399 1400 XMLGregorianCalendar lhs = this; 1401 1402 int result = DatatypeConstants.INDETERMINATE; 1403 XMLGregorianCalendarImpl P = (XMLGregorianCalendarImpl) lhs; 1404 XMLGregorianCalendarImpl Q = (XMLGregorianCalendarImpl) rhs; 1405 1406 if (P.getTimezone() == Q.getTimezone()) { 1407 return internalCompare(P, Q); 1412 1413 } else if (P.getTimezone() != DatatypeConstants.FIELD_UNDEFINED && 1414 Q.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) { 1415 1416 P = (XMLGregorianCalendarImpl) P.normalize(); 1419 Q = (XMLGregorianCalendarImpl) Q.normalize(); 1420 return internalCompare(P, Q); 1421 } else if (P.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) { 1422 1423 if (P.getTimezone() != 0) { 1424 P = (XMLGregorianCalendarImpl) P.normalize(); 1425 } 1426 1427 XMLGregorianCalendar MinQ = Q.normalizeToTimezone(DatatypeConstants.MIN_TIMEZONE_OFFSET); 1429 result = internalCompare(P, MinQ); 1430 if (result == DatatypeConstants.LESSER) { 1431 return result; 1432 } 1433 1434 XMLGregorianCalendar MaxQ = Q.normalizeToTimezone(DatatypeConstants.MAX_TIMEZONE_OFFSET); 1436 result = internalCompare(P, MaxQ); 1437 if (result == DatatypeConstants.GREATER) { 1438 return result; 1439 } else { 1440 return DatatypeConstants.INDETERMINATE; 1442 } 1443 } else { if (Q.getTimezone() != 0 ) { 1446 Q = (XMLGregorianCalendarImpl) Q.normalizeToTimezone(Q.getTimezone()); 1447 } 1448 1449 XMLGregorianCalendar MaxP = P.normalizeToTimezone(DatatypeConstants.MAX_TIMEZONE_OFFSET); 1451 result = internalCompare(MaxP, Q); 1452 if (result == DatatypeConstants.LESSER) { 1453 return result; 1454 } 1455 1456 XMLGregorianCalendar MinP = P.normalizeToTimezone(DatatypeConstants.MIN_TIMEZONE_OFFSET); 1458 result = internalCompare(MinP, Q); 1459 if (result == DatatypeConstants.GREATER) { 1460 return result; 1461 } else { 1462 return DatatypeConstants.INDETERMINATE; 1464 } 1465 } 1466 } 1467 1468 1474 public XMLGregorianCalendar normalize() { 1475 1476 XMLGregorianCalendar normalized = normalizeToTimezone(timezone); 1477 1478 if (getTimezone() == DatatypeConstants.FIELD_UNDEFINED) { 1480 normalized.setTimezone(DatatypeConstants.FIELD_UNDEFINED); 1481 } 1482 1483 if (getMillisecond() == DatatypeConstants.FIELD_UNDEFINED) { 1485 normalized.setMillisecond(DatatypeConstants.FIELD_UNDEFINED); 1486 } 1487 1488 return normalized; 1489 } 1490 1491 1497 private XMLGregorianCalendar normalizeToTimezone(int timezone) { 1498 1499 int minutes = timezone; 1500 XMLGregorianCalendar result = (XMLGregorianCalendar ) this.clone(); 1501 1502 minutes = -minutes; 1505 Duration d = new DurationImpl(minutes >= 0, 0, 0, 0, 0, minutes < 0 ? -minutes : minutes, 0 ); 1513 result.add(d); 1514 1515 result.setTimezone(0); 1517 return result; 1518 } 1519 1520 1534 private static int internalCompare(XMLGregorianCalendar P, 1535 XMLGregorianCalendar Q) { 1536 1537 int result; 1538 1539 if (P.getEon() == Q.getEon()) { 1541 1542 result = compareField(P.getYear(), Q.getYear()); 1545 if (result != DatatypeConstants.EQUAL) { 1546 return result; 1547 } 1548 } else { 1549 result = compareField(P.getEonAndYear(), Q.getEonAndYear()); 1550 if (result != DatatypeConstants.EQUAL) { 1551 return result; 1552 } 1553 } 1554 1555 result = compareField(P.getMonth(), Q.getMonth()); 1556 if (result != DatatypeConstants.EQUAL) { 1557 return result; 1558 } 1559 1560 result = compareField(P.getDay(), Q.getDay()); 1561 if (result != DatatypeConstants.EQUAL) { 1562 return result; 1563 } 1564 1565 result = compareField(P.getHour(), Q.getHour()); 1566 if (result != DatatypeConstants.EQUAL) { 1567 return result; 1568 } 1569 1570 result = compareField(P.getMinute(), Q.getMinute()); 1571 if (result != DatatypeConstants.EQUAL) { 1572 return result; 1573 } 1574 result = compareField(P.getSecond(), Q.getSecond()); 1575 if (result != DatatypeConstants.EQUAL) { 1576 return result; 1577 } 1578 1579 result = compareField(P.getFractionalSecond(), Q.getFractionalSecond()); 1580 return result; 1581 } 1582 1583 1587 private static int compareField(int Pfield, int Qfield) { 1588 if (Pfield == Qfield) { 1589 1590 return DatatypeConstants.EQUAL; 1593 } else { 1594 if (Pfield == DatatypeConstants.FIELD_UNDEFINED || Qfield == DatatypeConstants.FIELD_UNDEFINED) { 1595 return DatatypeConstants.INDETERMINATE; 1597 } else { 1598 return (Pfield < Qfield ? DatatypeConstants.LESSER : DatatypeConstants.GREATER); 1600 } 1601 } 1602 } 1603 1604 private static int compareField(BigInteger Pfield, BigInteger Qfield) { 1605 if (Pfield == null) { 1606 return (Qfield == null ? DatatypeConstants.EQUAL : DatatypeConstants.INDETERMINATE); 1607 } 1608 if (Qfield == null) { 1609 return DatatypeConstants.INDETERMINATE; 1610 } 1611 return Pfield.compareTo(Qfield); 1612 } 1613 1614 private static int compareField(BigDecimal Pfield, BigDecimal Qfield) { 1615 if (Pfield == Qfield) { 1617 return DatatypeConstants.EQUAL; 1618 } 1619 1620 if (Pfield == null) { 1621 Pfield = DECIMAL_ZERO; 1622 } 1623 1624 if (Qfield == null) { 1625 Qfield = DECIMAL_ZERO; 1626 } 1627 1628 return Pfield.compareTo(Qfield); 1629 } 1630 1631 1638 public boolean equals(Object obj) { 1639 boolean result = false; 1640 if (obj instanceof XMLGregorianCalendar ) { 1641 result = compare((XMLGregorianCalendar ) obj) == DatatypeConstants.EQUAL; 1642 } 1643 return result; 1644 } 1645 1646 1651 public int hashCode() { 1652 1653 int timezone = getTimezone(); 1659 if (timezone == DatatypeConstants.FIELD_UNDEFINED){ 1660 timezone = 0; 1661 } 1662 XMLGregorianCalendar gc = this; 1663 if (timezone != 0) { 1664 gc = this.normalizeToTimezone(getTimezone()); 1665 } 1666 return gc.getYear() + gc.getMonth() + gc.getDay() + 1667 gc.getHour() + gc.getMinute() + gc.getSecond(); 1668 } 1669 1670 1671 1701 public static XMLGregorianCalendar parse(String lexicalRepresentation) { 1702 1703 return new XMLGregorianCalendarImpl(lexicalRepresentation); 1704 } 1705 1706 1720 public String toXMLFormat() { 1721 1722 QName typekind = getXMLSchemaType(); 1723 1724 String formatString = null; 1725 if (typekind == DatatypeConstants.DATETIME) { 1726 formatString = "%Y-%M-%DT%h:%m:%s"+ "%z"; 1727 } else if (typekind == DatatypeConstants.DATE) { 1728 formatString = "%Y-%M-%D" +"%z"; 1730 } else if (typekind == DatatypeConstants.TIME) { 1731 formatString = "%h:%m:%s"+ "%z"; 1732 } else if (typekind == DatatypeConstants.GMONTH) { 1733 formatString = "--%M--%z"; 1734 } else if (typekind == DatatypeConstants.GDAY) { 1735 formatString = "---%D" + "%z"; 1737 } else if (typekind == DatatypeConstants.GYEAR) { 1738 formatString = "%Y" + "%z"; 1739 } else if (typekind == DatatypeConstants.GYEARMONTH) { 1740 formatString = "%Y-%M" + "%z"; 1742 } else if (typekind == DatatypeConstants.GMONTHDAY) { 1743 formatString = "--%M-%D" +"%z"; 1745 } 1746 return format(formatString); 1747 } 1748 1749 1860 public QName getXMLSchemaType() { 1861 1862 if (year != DatatypeConstants.FIELD_UNDEFINED 1864 && month != DatatypeConstants.FIELD_UNDEFINED 1865 && day != DatatypeConstants.FIELD_UNDEFINED 1866 && hour != DatatypeConstants.FIELD_UNDEFINED 1867 && minute != DatatypeConstants.FIELD_UNDEFINED 1868 && second != DatatypeConstants.FIELD_UNDEFINED) { 1869 return DatatypeConstants.DATETIME; 1870 } 1871 1872 if (year != DatatypeConstants.FIELD_UNDEFINED 1874 && month != DatatypeConstants.FIELD_UNDEFINED 1875 && day != DatatypeConstants.FIELD_UNDEFINED 1876 && hour == DatatypeConstants.FIELD_UNDEFINED 1877 && minute == DatatypeConstants.FIELD_UNDEFINED 1878 && second == DatatypeConstants.FIELD_UNDEFINED) { 1879 return DatatypeConstants.DATE; 1880 } 1881 1882 if (year == DatatypeConstants.FIELD_UNDEFINED 1884 && month == DatatypeConstants.FIELD_UNDEFINED 1885 && day == DatatypeConstants.FIELD_UNDEFINED 1886 && hour != DatatypeConstants.FIELD_UNDEFINED 1887 && minute != DatatypeConstants.FIELD_UNDEFINED 1888 && second != DatatypeConstants.FIELD_UNDEFINED) { 1889 return DatatypeConstants.TIME; 1890 } 1891 1892 1893 if (year != DatatypeConstants.FIELD_UNDEFINED 1895 && month != DatatypeConstants.FIELD_UNDEFINED 1896 && day == DatatypeConstants.FIELD_UNDEFINED 1897 && hour == DatatypeConstants.FIELD_UNDEFINED 1898 && minute == DatatypeConstants.FIELD_UNDEFINED 1899 && second == DatatypeConstants.FIELD_UNDEFINED) { 1900 return DatatypeConstants.GYEARMONTH; 1901 } 1902 1903 if (year == DatatypeConstants.FIELD_UNDEFINED 1905 && month != DatatypeConstants.FIELD_UNDEFINED 1906 && day != DatatypeConstants.FIELD_UNDEFINED 1907 && hour == DatatypeConstants.FIELD_UNDEFINED 1908 && minute == DatatypeConstants.FIELD_UNDEFINED 1909 && second == DatatypeConstants.FIELD_UNDEFINED) { 1910 return DatatypeConstants.GMONTHDAY; 1911 } 1912 1913 if (year != DatatypeConstants.FIELD_UNDEFINED 1915 && month == DatatypeConstants.FIELD_UNDEFINED 1916 && day == DatatypeConstants.FIELD_UNDEFINED 1917 && hour == DatatypeConstants.FIELD_UNDEFINED 1918 && minute == DatatypeConstants.FIELD_UNDEFINED 1919 && second == DatatypeConstants.FIELD_UNDEFINED) { 1920 return DatatypeConstants.GYEAR; 1921 } 1922 1923 if (year == DatatypeConstants.FIELD_UNDEFINED 1925 && month != DatatypeConstants.FIELD_UNDEFINED 1926 && day == DatatypeConstants.FIELD_UNDEFINED 1927 && hour == DatatypeConstants.FIELD_UNDEFINED 1928 && minute == DatatypeConstants.FIELD_UNDEFINED 1929 && second == DatatypeConstants.FIELD_UNDEFINED) { 1930 return DatatypeConstants.GMONTH; 1931 } 1932 1933 if (year == DatatypeConstants.FIELD_UNDEFINED 1935 && month == DatatypeConstants.FIELD_UNDEFINED 1936 && day != DatatypeConstants.FIELD_UNDEFINED 1937 && hour == DatatypeConstants.FIELD_UNDEFINED 1938 && minute == DatatypeConstants.FIELD_UNDEFINED 1939 && second == DatatypeConstants.FIELD_UNDEFINED) { 1940 return DatatypeConstants.GDAY; 1941 } 1942 1943 throw new IllegalStateException ( 1945 this.getClass().getName() 1946 + "#getXMLSchemaType() :" 1947 + DatatypeMessageFormatter.formatMessage(null, "InvalidXGCFields", null) 1948 ); 1949 } 1950 1951 1952 1956 public boolean isValid() { 1957 1962 if (getMonth() == DatatypeConstants.FEBRUARY) { 1964 int maxDays = DatatypeConstants.FIELD_UNDEFINED; 1966 BigInteger years = getEonAndYear(); 1967 if (years != null) { 1968 maxDays = maximumDayInMonthFor(getEonAndYear(), DatatypeConstants.FEBRUARY); 1969 } else { 1970 maxDays = 29; 1972 } 1973 if (getDay() > maxDays) { 1974 return false; 1975 } 1976 } 1977 1978 if (getHour() == 24) { 1980 if(getMinute() != 0) { 1981 return false; 1982 } else if (getSecond() != 0) { 1983 return false; 1984 } 1985 } 1986 1987 if (eon == null) { 1992 if (year == 0) { 1994 return false; 1995 } 1996 } else { 1997 BigInteger yearField = getEonAndYear(); 1998 if (yearField != null) { 1999 int result = compareField(yearField, BigInteger.ZERO); 2000 if (result == DatatypeConstants.EQUAL) { 2001 return false; 2002 } 2003 } 2004 } 2005 return true; 2006 } 2007 2008 2022 public void add(Duration duration) { 2023 2024 2047 2048 boolean fieldUndefined[] = { 2049 false, 2050 false, 2051 false, 2052 false, 2053 false, 2054 false 2055 }; 2056 2057 int signum = duration.getSign(); 2058 2059 int startMonth = getMonth(); 2060 if (startMonth == DatatypeConstants.FIELD_UNDEFINED) { 2061 startMonth = MIN_FIELD_VALUE[MONTH]; 2062 fieldUndefined[MONTH] = true; 2063 } 2064 2065 BigInteger dMonths = sanitize(duration.getField(DatatypeConstants.MONTHS), signum); 2066 BigInteger temp = BigInteger.valueOf((long) startMonth).add(dMonths); 2067 setMonth(temp.subtract(BigInteger.ONE).mod(TWELVE).intValue() + 1); 2068 BigInteger carry = 2069 new BigDecimal (temp.subtract(BigInteger.ONE)).divide(new BigDecimal (TWELVE), BigDecimal.ROUND_FLOOR).toBigInteger(); 2070 2071 2074 BigInteger startYear = getEonAndYear(); 2075 if (startYear == null) { 2076 fieldUndefined[YEAR] = true; 2077 startYear = BigInteger.ZERO; 2078 } 2079 BigInteger dYears = sanitize(duration.getField(DatatypeConstants.YEARS), signum); 2080 BigInteger endYear = startYear.add(dYears).add(carry); 2081 setYear(endYear); 2082 2083 2088 2089 2094 BigDecimal startSeconds; 2095 if (getSecond() == DatatypeConstants.FIELD_UNDEFINED) { 2096 fieldUndefined[SECOND] = true; 2097 startSeconds = DECIMAL_ZERO; 2098 } else { 2099 startSeconds = getSeconds(); 2101 } 2102 2103 BigDecimal dSeconds = DurationImpl.sanitize((BigDecimal ) duration.getField(DatatypeConstants.SECONDS), signum); 2105 BigDecimal tempBD = startSeconds.add(dSeconds); 2106 BigDecimal fQuotient = 2107 new BigDecimal (new BigDecimal (tempBD.toBigInteger()).divide(DECIMAL_SIXTY, BigDecimal.ROUND_FLOOR).toBigInteger()); 2108 BigDecimal endSeconds = tempBD.subtract(fQuotient.multiply(DECIMAL_SIXTY)); 2109 2110 carry = fQuotient.toBigInteger(); 2111 setSecond(endSeconds.intValue()); 2112 BigDecimal tempFracSeconds = endSeconds.subtract(new BigDecimal (BigInteger.valueOf((long) getSecond()))); 2113 if (tempFracSeconds.compareTo(DECIMAL_ZERO) < 0) { 2114 setFractionalSecond(DECIMAL_ONE.add(tempFracSeconds)); 2115 if (getSecond() == 0) { 2116 setSecond(59); 2117 carry = carry.subtract(BigInteger.ONE); 2118 } else { 2119 setSecond(getSecond() - 1); 2120 } 2121 } else { 2122 setFractionalSecond(tempFracSeconds); 2123 } 2124 2125 2130 int startMinutes = getMinute(); 2131 if (startMinutes == DatatypeConstants.FIELD_UNDEFINED) { 2132 fieldUndefined[MINUTE] = true; 2133 startMinutes = MIN_FIELD_VALUE[MINUTE]; 2134 } 2135 BigInteger dMinutes = sanitize(duration.getField(DatatypeConstants.MINUTES), signum); 2136 2137 temp = BigInteger.valueOf(startMinutes).add(dMinutes).add(carry); 2138 setMinute(temp.mod(SIXTY).intValue()); 2139 carry = new BigDecimal (temp).divide(DECIMAL_SIXTY, BigDecimal.ROUND_FLOOR).toBigInteger(); 2140 2141 2146 int startHours = getHour(); 2147 if (startHours == DatatypeConstants.FIELD_UNDEFINED) { 2148 fieldUndefined[HOUR] = true; 2149 startHours = MIN_FIELD_VALUE[HOUR]; 2150 } 2151 BigInteger dHours = sanitize(duration.getField(DatatypeConstants.HOURS), signum); 2152 2153 temp = BigInteger.valueOf(startHours).add(dHours).add(carry); 2154 setHour(temp.mod(TWENTY_FOUR).intValue()); 2155 carry = new BigDecimal (temp).divide(new BigDecimal (TWENTY_FOUR), BigDecimal.ROUND_FLOOR).toBigInteger(); 2156 2157 2180 BigInteger tempDays; 2181 int startDay = getDay(); 2182 if (startDay == DatatypeConstants.FIELD_UNDEFINED) { 2183 fieldUndefined[DAY] = true; 2184 startDay = MIN_FIELD_VALUE[DAY]; 2185 } 2186 BigInteger dDays = sanitize(duration.getField(DatatypeConstants.DAYS), signum); 2187 int maxDayInMonth = maximumDayInMonthFor(getEonAndYear(), getMonth()); 2188 if (startDay > maxDayInMonth) { 2189 tempDays = BigInteger.valueOf(maxDayInMonth); 2190 } else if (startDay < 1) { 2191 tempDays = BigInteger.ONE; 2192 } else { 2193 tempDays = BigInteger.valueOf(startDay); 2194 } 2195 BigInteger endDays = tempDays.add(dDays).add(carry); 2196 int monthCarry; 2197 int intTemp; 2198 while (true) { 2199 if (endDays.compareTo(BigInteger.ONE) < 0) { 2200 BigInteger mdimf = null; 2202 if (month >= 2) { 2203 mdimf = BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear(), getMonth() - 1)); 2204 } else { 2205 mdimf = BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear().subtract(BigInteger.valueOf((long) 1)), 12)); 2207 } 2208 endDays = endDays.add(mdimf); 2209 monthCarry = -1; 2210 } else if (endDays.compareTo(BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear(), getMonth()))) > 0) { 2211 endDays = endDays.add(BigInteger.valueOf(-maximumDayInMonthFor(getEonAndYear(), getMonth()))); 2212 monthCarry = 1; 2213 } else { 2214 break; 2215 } 2216 2217 intTemp = getMonth() + monthCarry; 2218 int endMonth = (intTemp - 1) % (13 - 1); 2219 int quotient; 2220 if (endMonth < 0) { 2221 endMonth = (13 - 1) + endMonth + 1; 2222 quotient = new BigDecimal (intTemp - 1).divide(new BigDecimal (TWELVE), BigDecimal.ROUND_UP).intValue(); 2223 } else { 2224 quotient = (intTemp - 1) / (13 - 1); 2225 endMonth += 1; 2226 } 2227 setMonth(endMonth); 2228 if (quotient != 0) { 2229 setYear(getEonAndYear().add(BigInteger.valueOf(quotient))); 2230 } 2231 } 2232 setDay(endDays.intValue()); 2233 2234 for (int i = YEAR; i <= SECOND; i++) { 2236 if (fieldUndefined[i]) { 2237 switch (i) { 2238 case YEAR: 2239 setYear(DatatypeConstants.FIELD_UNDEFINED); 2240 break; 2241 case MONTH: 2242 setMonth(DatatypeConstants.FIELD_UNDEFINED); 2243 break; 2244 case DAY: 2245 setDay(DatatypeConstants.FIELD_UNDEFINED); 2246 break; 2247 case HOUR: 2248 setHour(DatatypeConstants.FIELD_UNDEFINED); 2249 break; 2250 case MINUTE: 2251 setMinute(DatatypeConstants.FIELD_UNDEFINED); 2252 break; 2253 case SECOND: 2254 setSecond(DatatypeConstants.FIELD_UNDEFINED); 2255 setFractionalSecond(null); 2256 break; 2257 } 2258 } 2259 } 2260 } 2261 2262 private static final BigInteger FOUR = BigInteger.valueOf(4); 2263 private static final BigInteger HUNDRED = BigInteger.valueOf(100); 2264 private static final BigInteger FOUR_HUNDRED = BigInteger.valueOf(400); 2265 private static final BigInteger SIXTY = BigInteger.valueOf(60); 2266 private static final BigInteger TWENTY_FOUR = BigInteger.valueOf(24); 2267 private static final BigInteger TWELVE = BigInteger.valueOf(12); 2268 private static final BigDecimal DECIMAL_ZERO = new BigDecimal ("0"); 2269 private static final BigDecimal DECIMAL_ONE = new BigDecimal ("1"); 2270 private static final BigDecimal DECIMAL_SIXTY = new BigDecimal ("60"); 2271 2272 2273 private static int daysInMonth[] = { 0, 31, 28, 31, 30, 31, 30, 2275 31, 31, 30, 31, 30, 31}; 2276 2277 private static int maximumDayInMonthFor(BigInteger year, int month) { 2278 if (month != DatatypeConstants.FEBRUARY) { 2279 return daysInMonth[month]; 2280 } else { 2281 if (year.mod(FOUR_HUNDRED).equals(BigInteger.ZERO) || 2282 (!year.mod(HUNDRED).equals(BigInteger.ZERO) && 2283 year.mod(FOUR).equals(BigInteger.ZERO))) { 2284 return 29; 2286 } else { 2287 return daysInMonth[month]; 2288 } 2289 } 2290 } 2291 2292 private static int maximumDayInMonthFor(int year, int month) { 2293 if (month != DatatypeConstants.FEBRUARY) { 2294 return daysInMonth[month]; 2295 } else { 2296 if ( ((year %400) == 0) || 2297 ( ((year % 100) != 0) && ((year % 4) == 0))) { 2298 return 29; 2300 } else { 2301 return daysInMonth[DatatypeConstants.FEBRUARY]; 2302 } 2303 } 2304 } 2305 2306 2398 public java.util.GregorianCalendar toGregorianCalendar() { 2399 2400 GregorianCalendar result = null; 2401 final int DEFAULT_TIMEZONE_OFFSET = DatatypeConstants.FIELD_UNDEFINED; 2402 TimeZone tz = getTimeZone(DEFAULT_TIMEZONE_OFFSET); 2403 Locale locale = java.util.Locale.getDefault(); 2404 2405 result = new GregorianCalendar (tz, locale); 2406 result.clear(); 2407 result.setGregorianChange(PURE_GREGORIAN_CHANGE); 2408 2409 BigInteger year = getEonAndYear(); 2411 if (year != null) { 2412 result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD); 2413 result.set(Calendar.YEAR, year.abs().intValue()); 2414 } 2415 2416 if (month != DatatypeConstants.FIELD_UNDEFINED) { 2418 result.set(Calendar.MONTH, month - 1); 2420 } 2421 2422 if (day != DatatypeConstants.FIELD_UNDEFINED) { 2424 result.set(Calendar.DAY_OF_MONTH, day); 2425 } 2426 2427 if (hour != DatatypeConstants.FIELD_UNDEFINED) { 2429 result.set(Calendar.HOUR_OF_DAY, hour); 2430 } 2431 2432 if (minute != DatatypeConstants.FIELD_UNDEFINED) { 2434 result.set(Calendar.MINUTE, minute); 2435 } 2436 2437 if (second != DatatypeConstants.FIELD_UNDEFINED) { 2439 result.set(Calendar.SECOND, second); 2440 } 2441 2442 if (fractionalSecond != null) { 2444 result.set(Calendar.MILLISECOND, getMillisecond()); 2445 } 2446 2447 return result; 2448 } 2449 2450 2502 public GregorianCalendar toGregorianCalendar(java.util.TimeZone timezone, 2503 java.util.Locale aLocale, 2504 XMLGregorianCalendar defaults) { 2505 GregorianCalendar result = null; 2506 TimeZone tz = timezone; 2507 if (tz == null) { 2508 int defaultZoneoffset = DatatypeConstants.FIELD_UNDEFINED; 2509 if (defaults != null) { 2510 defaultZoneoffset = defaults.getTimezone(); 2511 } 2512 tz = getTimeZone(defaultZoneoffset); 2513 } 2514 if (aLocale == null) { 2515 aLocale = java.util.Locale.getDefault(); 2516 } 2517 result = new GregorianCalendar (tz, aLocale); 2518 result.clear(); 2519 result.setGregorianChange(PURE_GREGORIAN_CHANGE); 2520 2521 BigInteger year = getEonAndYear(); 2523 if (year != null) { 2524 result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD); 2525 result.set(Calendar.YEAR, year.abs().intValue()); 2526 } else { 2527 BigInteger defaultYear = (defaults != null) ? defaults.getEonAndYear() : null; 2529 if (defaultYear != null) { 2530 result.set(Calendar.ERA, defaultYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD); 2531 result.set(Calendar.YEAR, defaultYear.abs().intValue()); 2532 } 2533 } 2534 2535 if (month != DatatypeConstants.FIELD_UNDEFINED) { 2537 result.set(Calendar.MONTH, month - 1); 2539 } else { 2540 int defaultMonth = (defaults != null) ? defaults.getMonth() : DatatypeConstants.FIELD_UNDEFINED; 2542 if (defaultMonth != DatatypeConstants.FIELD_UNDEFINED) { 2543 result.set(Calendar.MONTH, defaultMonth - 1); 2545 } 2546 } 2547 2548 if (day != DatatypeConstants.FIELD_UNDEFINED) { 2550 result.set(Calendar.DAY_OF_MONTH, day); 2551 } else { 2552 int defaultDay = (defaults != null) ? defaults.getDay() : DatatypeConstants.FIELD_UNDEFINED; 2554 if (defaultDay != DatatypeConstants.FIELD_UNDEFINED) { 2555 result.set(Calendar.DAY_OF_MONTH, defaultDay); 2556 } 2557 } 2558 2559 if (hour != DatatypeConstants.FIELD_UNDEFINED) { 2561 result.set(Calendar.HOUR_OF_DAY, hour); 2562 } else { 2563 int defaultHour = (defaults != null) ? defaults.getHour() : DatatypeConstants.FIELD_UNDEFINED; 2565 if (defaultHour != DatatypeConstants.FIELD_UNDEFINED) { 2566 result.set(Calendar.HOUR_OF_DAY, defaultHour); 2567 } 2568 } 2569 2570 if (minute != DatatypeConstants.FIELD_UNDEFINED) { 2572 result.set(Calendar.MINUTE, minute); 2573 } else { 2574 int defaultMinute = (defaults != null) ? defaults.getMinute() : DatatypeConstants.FIELD_UNDEFINED; 2576 if (defaultMinute != DatatypeConstants.FIELD_UNDEFINED) { 2577 result.set(Calendar.MINUTE, defaultMinute); 2578 } 2579 } 2580 2581 if (second != DatatypeConstants.FIELD_UNDEFINED) { 2583 result.set(Calendar.SECOND, second); 2584 } else { 2585 int defaultSecond = (defaults != null) ? defaults.getSecond() : DatatypeConstants.FIELD_UNDEFINED; 2587 if (defaultSecond != DatatypeConstants.FIELD_UNDEFINED) { 2588 result.set(Calendar.SECOND, defaultSecond); 2589 } 2590 } 2591 2592 if (fractionalSecond != null) { 2594 result.set(Calendar.MILLISECOND, getMillisecond()); 2595 } else { 2596 BigDecimal defaultFractionalSecond = (defaults != null) ? defaults.getFractionalSecond() : null; 2598 if (defaultFractionalSecond != null) { 2599 result.set(Calendar.MILLISECOND, defaults.getMillisecond()); 2600 } 2601 } 2602 2603 return result; 2604 } 2605 2606 2622 public TimeZone getTimeZone(int defaultZoneoffset) { 2623 TimeZone result = null; 2624 int zoneoffset = getTimezone(); 2625 2626 if (zoneoffset == DatatypeConstants.FIELD_UNDEFINED) { 2627 zoneoffset = defaultZoneoffset; 2628 } 2629 if (zoneoffset == DatatypeConstants.FIELD_UNDEFINED) { 2630 result = TimeZone.getDefault(); 2631 } else { 2632 char sign = zoneoffset < 0 ? '-' : '+'; 2634 if (sign == '-') { 2635 zoneoffset = -zoneoffset; 2636 } 2637 int hour = zoneoffset / 60; 2638 int minutes = zoneoffset - (hour * 60); 2639 2640 StringBuffer customTimezoneId = new StringBuffer (8); 2646 customTimezoneId.append("GMT"); 2647 customTimezoneId.append(sign); 2648 customTimezoneId.append(hour); 2649 if (minutes != 0) { 2650 customTimezoneId.append(minutes); 2651 } 2652 result = TimeZone.getTimeZone(customTimezoneId.toString()); 2653 } 2654 return result; 2655 } 2656 2657 2662 public Object clone() { 2663 return new XMLGregorianCalendarImpl(getEonAndYear(), 2666 this.month, this.day, 2667 this.hour, this.minute, this.second, 2668 this.fractionalSecond, 2669 this.timezone); 2670 } 2671 2672 2678 public void clear() { 2679 eon = null; 2680 year = DatatypeConstants.FIELD_UNDEFINED; 2681 month = DatatypeConstants.FIELD_UNDEFINED; 2682 day = DatatypeConstants.FIELD_UNDEFINED; 2683 timezone = DatatypeConstants.FIELD_UNDEFINED; hour = DatatypeConstants.FIELD_UNDEFINED; 2685 minute = DatatypeConstants.FIELD_UNDEFINED; 2686 second = DatatypeConstants.FIELD_UNDEFINED; 2687 fractionalSecond = null; 2688 } 2689 2690 public void setMillisecond(int millisecond) { 2691 if (millisecond == DatatypeConstants.FIELD_UNDEFINED) { 2692 fractionalSecond = null; 2693 } else { 2694 checkFieldValueConstraint(MILLISECOND, millisecond); 2695 fractionalSecond = new BigDecimal ((long) millisecond).movePointLeft(3); 2696 } 2697 } 2698 2699 public void setFractionalSecond(BigDecimal fractional) { 2700 if (fractional != null) { 2701 if ((fractional.compareTo(DECIMAL_ZERO) < 0) || 2702 (fractional.compareTo(DECIMAL_ONE) > 0)) { 2703 throw new IllegalArgumentException (DatatypeMessageFormatter.formatMessage(null, 2704 "InvalidFractional", new Object []{fractional})); 2705 } 2706 } 2707 this.fractionalSecond = fractional; 2708 } 2709 2710 private final class Parser { 2711 private final String format; 2712 private final String value; 2713 2714 private final int flen; 2715 private final int vlen; 2716 2717 private int fidx; 2718 private int vidx; 2719 2720 private Parser(String format, String value) { 2721 this.format = format; 2722 this.value = value; 2723 this.flen = format.length(); 2724 this.vlen = value.length(); 2725 } 2726 2727 2735 public void parse() throws IllegalArgumentException { 2736 while (fidx < flen) { 2737 char fch = format.charAt(fidx++); 2738 2739 if (fch != '%') { skip(fch); 2741 continue; 2742 } 2743 2744 switch (format.charAt(fidx++)) { 2746 case 'Y' : setYear(parseBigInteger(4)); 2748 break; 2749 2750 case 'M' : setMonth(parseInt(2, 2)); 2752 break; 2753 2754 case 'D' : setDay(parseInt(2, 2)); 2756 break; 2757 2758 case 'h' : setHour(parseInt(2, 2)); 2760 break; 2761 2762 case 'm' : setMinute(parseInt(2, 2)); 2764 break; 2765 2766 case 's' : setSecond(parseInt(2, 2)); 2768 2769 if (peek() == '.') { 2770 setFractionalSecond(parseBigDecimal()); 2771 } 2772 break; 2773 2774 case 'z' : char vch = peek(); 2776 if (vch == 'Z') { 2777 vidx++; 2778 setTimezone(0); 2779 } else if (vch == '+' || vch == '-') { 2780 vidx++; 2781 int h = parseInt(2, 2); 2782 skip(':'); 2783 int m = parseInt(2, 2); 2784 setTimezone((h * 60 + m) * (vch == '+' ? 1 : -1)); 2785 } 2786 2787 break; 2788 2789 default : 2790 throw new InternalError (); 2792 } 2793 } 2794 2795 if (vidx != vlen) { 2796 throw new IllegalArgumentException (value); } 2799 } 2800 2801 private char peek() throws IllegalArgumentException { 2802 if (vidx == vlen) { 2803 return (char) -1; 2804 } 2805 return value.charAt(vidx); 2806 } 2807 2808 private char read() throws IllegalArgumentException { 2809 if (vidx == vlen) { 2810 throw new IllegalArgumentException (value); } 2812 return value.charAt(vidx++); 2813 } 2814 2815 private void skip(char ch) throws IllegalArgumentException { 2816 if (read() != ch) { 2817 throw new IllegalArgumentException (value); } 2819 } 2820 2821 private int parseInt(int minDigits, int maxDigits) 2822 throws IllegalArgumentException { 2823 int vstart = vidx; 2824 while (isDigit(peek()) && (vidx - vstart) <= maxDigits) { 2825 vidx++; 2826 } 2827 if ((vidx - vstart) < minDigits) { 2828 throw new IllegalArgumentException (value); } 2831 2832 return Integer.parseInt(value.substring(vstart, vidx)); 2835 } 2840 2841 private BigInteger parseBigInteger(int minDigits) 2842 throws IllegalArgumentException { 2843 int vstart = vidx; 2844 2845 if (peek() == '-') { 2847 vidx++; 2848 } 2849 while (isDigit(peek())) { 2850 vidx++; 2851 } 2852 if ((vidx - vstart) < minDigits) { 2853 throw new IllegalArgumentException (value); } 2856 2857 return new BigInteger (value.substring(vstart, vidx)); 2858 } 2859 2860 private BigDecimal parseBigDecimal() 2861 throws IllegalArgumentException { 2862 int vstart = vidx; 2863 2864 if (peek() == '.') { 2865 vidx++; 2866 } else { 2867 throw new IllegalArgumentException (value); 2868 } 2869 while (isDigit(peek())) { 2870 vidx++; 2871 } 2872 return new BigDecimal (value.substring(vstart, vidx)); 2873 } 2874 } 2875 2876 private static boolean isDigit(char ch) { 2877 return '0' <= ch && ch <= '9'; 2878 } 2879 2880 private String format( String format ) { 2881 StringBuffer buf = new StringBuffer (); 2882 int fidx=0,flen=format.length(); 2883 2884 while(fidx<flen) { 2885 char fch = format.charAt(fidx++); 2886 if(fch!='%') { buf.append(fch); 2888 continue; 2889 } 2890 2891 switch(format.charAt(fidx++)) { 2892 case 'Y': 2893 printNumber(buf,getEonAndYear(), 4); 2894 break; 2895 case 'M': 2896 printNumber(buf,getMonth(),2); 2897 break; 2898 case 'D': 2899 printNumber(buf,getDay(),2); 2900 break; 2901 case 'h': 2902 printNumber(buf,getHour(),2); 2903 break; 2904 case 'm': 2905 printNumber(buf,getMinute(),2); 2906 break; 2907 case 's': 2908 printNumber(buf,getSecond(),2); 2909 if (getFractionalSecond() != null) { 2910 String frac = getFractionalSecond().toString(); 2911 buf.append(frac.substring(1, frac.length())); 2913 } 2914 break; 2915 case 'z': 2916 int offset = getTimezone(); 2917 if(offset == 0) { 2918 buf.append('Z'); 2919 } else if (offset != DatatypeConstants.FIELD_UNDEFINED) { 2920 if(offset<0) { 2921 buf.append('-'); 2922 offset *= -1; 2923 } else { 2924 buf.append('+'); 2925 } 2926 printNumber(buf,offset/60,2); 2927 buf.append(':'); 2928 printNumber(buf,offset%60,2); 2929 } 2930 break; 2931 default: 2932 throw new InternalError (); } 2934 } 2935 2936 return buf.toString(); 2937 } 2938 2939 2951 private void printNumber( StringBuffer out, int number, int nDigits ) { 2952 String s = String.valueOf(number); 2953 for( int i=s.length(); i<nDigits; i++ ) 2954 out.append('0'); 2955 out.append(s); 2956 } 2957 2958 2970 private void printNumber( StringBuffer out, BigInteger number, int nDigits) { 2971 String s = number.toString(); 2972 for( int i=s.length(); i<nDigits; i++ ) 2973 out.append('0'); 2974 out.append(s); 2975 } 2976 2977 2982 static BigInteger sanitize(Number value, int signum) { 2983 if (signum == 0 || value == null) { 2984 return BigInteger.ZERO; 2985 } 2986 return (signum < 0)? ((BigInteger )value).negate() : (BigInteger )value; 2987 } 2988 2989 2993 public void reset() { 2994 } 2996} 2997 2998 | Popular Tags |