36 * 37 */ 38 39 package java.util; 40 41 import java.io.IOException; 42 import java.io.ObjectInputStream; 43 import java.io.ObjectOutputStream; 44 import java.io.OptionalDataException; 45 import java.io.Serializable; 46 import java.security.AccessControlContext; 47 import java.security.AccessController; 48 import java.security.PermissionCollection; 49 import java.security.PrivilegedActionException; 50 import java.security.PrivilegedExceptionAction; 51 import java.security.ProtectionDomain; 52 import java.text.DateFormat; 53 import java.text.DateFormatSymbols; 54 import java.util.concurrent.ConcurrentHashMap; 55 import java.util.concurrent.ConcurrentMap; 56 import java.util.spi.CalendarDataProvider; 57 import sun.util.BuddhistCalendar; 58 import sun.util.locale.provider.LocaleProviderAdapter; 59 import sun.util.calendar.ZoneInfo; 60 import sun.util.locale.provider.CalendarDataUtility; 61 62 /** 63 * The <code>Calendar</code> class is an abstract class that provides methods 64 * for converting between a specific instant in time and a set of {@link 65 * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>, 66 * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for 67 * manipulating the calendar fields, such as getting the date of the next 68 * week. An instant in time can be represented by a millisecond value that is 69 * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970 70 * 00:00:00.000 GMT (Gregorian). 71 * 72 * <p>The class also provides additional fields and methods for 73 * implementing a concrete calendar system outside the package. Those 74 * fields and methods are defined as <code>protected</code>. 75 * 76 * <p> 77 * Like other locale-sensitive classes, <code>Calendar</code> provides a 78 * class method, <code>getInstance</code>, for getting a generally useful 729 * @see #SHORT_STANDALONE 730 * @see #LONG 731 * @since 1.6 732 */ 733 public static final int SHORT = 1; 734 735 /** 736 * A style specifier for {@link #getDisplayName(int, int, Locale) 737 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 738 * getDisplayNames} equivalent to {@link #LONG_FORMAT}. 739 * 740 * @see #LONG_STANDALONE 741 * @see #SHORT 742 * @since 1.6 743 */ 744 public static final int LONG = 2; 745 746 /** 747 * A style specifier for {@link #getDisplayName(int, int, Locale) 748 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 749 * getDisplayNames} indicating a short name used for format. 750 * 751 * @see #SHORT_STANDALONE 752 * @see #LONG_FORMAT 753 * @see #LONG_STANDALONE 754 * @since 1.8 755 */ 756 public static final int SHORT_FORMAT = 1; 757 758 /** 759 * A style specifier for {@link #getDisplayName(int, int, Locale) 760 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 761 * getDisplayNames} indicating a long name used for format. 762 * 763 * @see #LONG_STANDALONE 764 * @see #SHORT_FORMAT 765 * @see #SHORT_STANDALONE 766 * @since 1.8 767 */ 768 public static final int LONG_FORMAT = 2; 1455 * applicable to the given calendar <code>field</code>. 1456 * 1457 * <p>For example, if this <code>Calendar</code> is a 1458 * <code>GregorianCalendar</code> and its date is 2005-01-01, then 1459 * the string representation of the {@link #MONTH} field would be 1460 * "January" in the long style in an English locale or "Jan" in 1461 * the short style. However, no string representation would be 1462 * available for the {@link #DAY_OF_MONTH} field, and this method 1463 * would return <code>null</code>. 1464 * 1465 * <p>The default implementation supports the calendar fields for 1466 * which a {@link DateFormatSymbols} has names in the given 1467 * <code>locale</code>. 1468 * 1469 * @param field 1470 * the calendar field for which the string representation 1471 * is returned 1472 * @param style 1473 * the style applied to the string representation; one of {@link 1474 * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 1475 * {@link #LONG_FORMAT} ({@link #LONG}) or {@link #LONG_STANDALONE}. 1476 * @param locale 1477 * the locale for the string representation 1478 * (any calendar types specified by {@code locale} are ignored) 1479 * @return the string representation of the given 1480 * <code>field</code> in the given <code>style</code>, or 1481 * <code>null</code> if no string representation is 1482 * applicable. 1483 * @exception IllegalArgumentException 1484 * if <code>field</code> or <code>style</code> is invalid, 1485 * or if this <code>Calendar</code> is non-lenient and any 1486 * of the calendar fields have invalid values 1487 * @exception NullPointerException 1488 * if <code>locale</code> is null 1489 * @since 1.6 1490 */ 1491 public String getDisplayName(int field, int style, Locale locale) { 1492 if (!checkDisplayNameParams(field, style, SHORT, LONG, locale, 1493 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 1494 return null; 1495 } 1496 1497 // the standalone styles are supported only through CalendarDataProviders. 1498 if (isStandaloneStyle(style)) { 1499 return CalendarDataUtility.retrieveFieldValueName(getCalendarType(), 1500 field, get(field), 1501 style, locale); 1502 } 1503 1504 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 1505 String[] strings = getFieldStrings(field, style, symbols); 1506 if (strings != null) { 1507 int fieldValue = get(field); 1508 if (fieldValue < strings.length) { 1509 return strings[fieldValue]; 1510 } 1511 } 1512 return null; 1513 } 1514 1515 /** 1516 * Returns a <code>Map</code> containing all names of the calendar 1517 * <code>field</code> in the given <code>style</code> and 1518 * <code>locale</code> and their corresponding field values. For 1519 * example, if this <code>Calendar</code> is a {@link 1520 * GregorianCalendar}, the returned map would contain "Jan" to 1521 * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the 1522 * {@linkplain #SHORT short} style in an English locale. 1523 * 1524 * <p>The values of other calendar fields may be taken into 1525 * account to determine a set of display names. For example, if 1526 * this <code>Calendar</code> is a lunisolar calendar system and 1527 * the year value given by the {@link #YEAR} field has a leap 1528 * month, this method would return month names containing the leap 1529 * month name, and month names are mapped to their values specific 1530 * for the year. 1531 * 1532 * <p>The default implementation supports display names contained in 1533 * a {@link DateFormatSymbols}. For example, if <code>field</code> 1534 * is {@link #MONTH} and <code>style</code> is {@link 1535 * #ALL_STYLES}, this method returns a <code>Map</code> containing 1536 * all strings returned by {@link DateFormatSymbols#getShortMonths()} 1537 * and {@link DateFormatSymbols#getMonths()}. 1538 * 1539 * @param field 1540 * the calendar field for which the display names are returned 1541 * @param style 1542 * the style applied to the string representation; one of {@link 1543 * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 1544 * {@link #LONG_FORMAT} ({@link #LONG}) or {@link #LONG_STANDALONE}. 1545 * @param locale 1546 * the locale for the display names 1547 * @return a <code>Map</code> containing all display names in 1548 * <code>style</code> and <code>locale</code> and their 1549 * field values, or <code>null</code> if no display names 1550 * are defined for <code>field</code> 1551 * @exception IllegalArgumentException 1552 * if <code>field</code> or <code>style</code> is invalid, 1553 * or if this <code>Calendar</code> is non-lenient and any 1554 * of the calendar fields have invalid values 1555 * @exception NullPointerException 1556 * if <code>locale</code> is null 1557 * @since 1.6 1558 */ 1559 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 1560 if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale, 1561 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 1562 return null; 1563 } 1564 if (style == ALL_STYLES || isStandaloneStyle(style)) { 1565 return CalendarDataUtility.retrieveFieldValueNames(getCalendarType(), field, style, locale); 1566 } 1567 // SHORT or LONG 1568 return getDisplayNamesImpl(field, style, locale); 1569 } 1570 1571 private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) { 1572 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 1573 String[] strings = getFieldStrings(field, style, symbols); 1574 if (strings != null) { 1575 Map<String,Integer> names = new HashMap<>(); 1576 for (int i = 0; i < strings.length; i++) { 1577 if (strings[i].length() == 0) { 1578 continue; 1579 } 1580 names.put(strings[i], i); 1581 } 1582 return names; 1583 } 1584 return null; 1585 } 1586 1587 boolean checkDisplayNameParams(int field, int style, int minStyle, int maxStyle, 1588 Locale locale, int fieldMask) { 1589 int baseStyle = getBaseStyle(style); // Ignore the standalone mask 1590 if (field < 0 || field >= fields.length || 1591 baseStyle < minStyle || baseStyle > maxStyle) { 1592 throw new IllegalArgumentException(); 1593 } 1594 if (locale == null) { 1595 throw new NullPointerException(); 1596 } 1597 return isFieldSet(fieldMask, field); 1598 } 1599 1600 private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) { 1601 int baseStyle = getBaseStyle(style); // ignore the standalone mask 1602 String[] strings = null; 1603 switch (field) { 1604 case ERA: 1605 strings = symbols.getEras(); 1606 break; 1607 1608 case MONTH: 1609 strings = (baseStyle == LONG) ? symbols.getMonths() : symbols.getShortMonths(); 1610 break; 1611 1612 case DAY_OF_WEEK: 1613 strings = (baseStyle == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays(); 1614 break; 1615 1616 case AM_PM: 1617 strings = symbols.getAmPmStrings(); 1618 break; 1619 } 1620 return strings; 1621 } 1929 } 1930 if (stamp[MILLISECOND] != UNSET) { 1931 fieldMask |= MILLISECOND_MASK; 1932 } 1933 if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) { 1934 fieldMask |= ZONE_OFFSET_MASK; 1935 } 1936 if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { 1937 fieldMask |= DST_OFFSET_MASK; 1938 } 1939 1940 return fieldMask; 1941 } 1942 1943 int getBaseStyle(int style) { 1944 return style & ~STANDALONE_MASK; 1945 } 1946 1947 boolean isStandaloneStyle(int style) { 1948 return (style & STANDALONE_MASK) != 0; 1949 } 1950 1951 /** 1952 * Returns the pseudo-time-stamp for two fields, given their 1953 * individual pseudo-time-stamps. If either of the fields 1954 * is unset, then the aggregate is unset. Otherwise, the 1955 * aggregate is the later of the two stamps. 1956 */ 1957 private static int aggregateStamp(int stamp_a, int stamp_b) { 1958 if (stamp_a == UNSET || stamp_b == UNSET) { 1959 return UNSET; 1960 } 1961 return (stamp_a > stamp_b) ? stamp_a : stamp_b; 1962 } 1963 1964 /** 1965 * Returns the calendar type of this {@code Calendar}. Calendar types are 1966 * defined by the <em>Unicode Locale Data Markup Language (LDML)</em> 1967 * specification. 1968 * | 36 * 37 */ 38 39 package java.util; 40 41 import java.io.IOException; 42 import java.io.ObjectInputStream; 43 import java.io.ObjectOutputStream; 44 import java.io.OptionalDataException; 45 import java.io.Serializable; 46 import java.security.AccessControlContext; 47 import java.security.AccessController; 48 import java.security.PermissionCollection; 49 import java.security.PrivilegedActionException; 50 import java.security.PrivilegedExceptionAction; 51 import java.security.ProtectionDomain; 52 import java.text.DateFormat; 53 import java.text.DateFormatSymbols; 54 import java.util.concurrent.ConcurrentHashMap; 55 import java.util.concurrent.ConcurrentMap; 56 import sun.util.BuddhistCalendar; 57 import sun.util.calendar.ZoneInfo; 58 import sun.util.locale.provider.CalendarDataUtility; 59 60 /** 61 * The <code>Calendar</code> class is an abstract class that provides methods 62 * for converting between a specific instant in time and a set of {@link 63 * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>, 64 * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for 65 * manipulating the calendar fields, such as getting the date of the next 66 * week. An instant in time can be represented by a millisecond value that is 67 * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970 68 * 00:00:00.000 GMT (Gregorian). 69 * 70 * <p>The class also provides additional fields and methods for 71 * implementing a concrete calendar system outside the package. Those 72 * fields and methods are defined as <code>protected</code>. 73 * 74 * <p> 75 * Like other locale-sensitive classes, <code>Calendar</code> provides a 76 * class method, <code>getInstance</code>, for getting a generally useful 727 * @see #SHORT_STANDALONE 728 * @see #LONG 729 * @since 1.6 730 */ 731 public static final int SHORT = 1; 732 733 /** 734 * A style specifier for {@link #getDisplayName(int, int, Locale) 735 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 736 * getDisplayNames} equivalent to {@link #LONG_FORMAT}. 737 * 738 * @see #LONG_STANDALONE 739 * @see #SHORT 740 * @since 1.6 741 */ 742 public static final int LONG = 2; 743 744 /** 745 * A style specifier for {@link #getDisplayName(int, int, Locale) 746 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 747 * getDisplayNames} indicating a narrow name used for format. Narrow names 748 * are typically single character strings, such as "M" for Monday. 749 * 750 * @see #NARROW_STANDALONE 751 * @see #SHORT_FORMAT 752 * @see #LONG_FOTMAT 753 * @since 1.8 754 */ 755 public static final int NARROW_FORMAT = 4; 756 757 /** 758 * A style specifier for {@link #getDisplayName(int, int, Locale) 759 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 760 * getDisplayNames} indicating a narrow name independently. Narrow names 761 * are typically single character strings, such as "M" for Monday. 762 * 763 * @see #NARROW_FORMAT 764 * @see #SHORT_STANDALONE 765 * @see #LONG_STANDALONE 766 * @since 1.8 767 */ 768 public static final int NARROW_STANDALONE = NARROW_FORMAT | STANDALONE_MASK; 769 770 /** 771 * A style specifier for {@link #getDisplayName(int, int, Locale) 772 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 773 * getDisplayNames} indicating a short name used for format. 774 * 775 * @see #SHORT_STANDALONE 776 * @see #LONG_FORMAT 777 * @see #LONG_STANDALONE 778 * @since 1.8 779 */ 780 public static final int SHORT_FORMAT = 1; 781 782 /** 783 * A style specifier for {@link #getDisplayName(int, int, Locale) 784 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 785 * getDisplayNames} indicating a long name used for format. 786 * 787 * @see #LONG_STANDALONE 788 * @see #SHORT_FORMAT 789 * @see #SHORT_STANDALONE 790 * @since 1.8 791 */ 792 public static final int LONG_FORMAT = 2; 1479 * applicable to the given calendar <code>field</code>. 1480 * 1481 * <p>For example, if this <code>Calendar</code> is a 1482 * <code>GregorianCalendar</code> and its date is 2005-01-01, then 1483 * the string representation of the {@link #MONTH} field would be 1484 * "January" in the long style in an English locale or "Jan" in 1485 * the short style. However, no string representation would be 1486 * available for the {@link #DAY_OF_MONTH} field, and this method 1487 * would return <code>null</code>. 1488 * 1489 * <p>The default implementation supports the calendar fields for 1490 * which a {@link DateFormatSymbols} has names in the given 1491 * <code>locale</code>. 1492 * 1493 * @param field 1494 * the calendar field for which the string representation 1495 * is returned 1496 * @param style 1497 * the style applied to the string representation; one of {@link 1498 * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 1499 * {@link #LONG_FORMAT} ({@link #LONG}), {@link #LONG_STANDALONE}, 1500 * {@link #NARROW_FORMAT}, or {@link #NARROW_STANDALONE}. 1501 * @param locale 1502 * the locale for the string representation 1503 * (any calendar types specified by {@code locale} are ignored) 1504 * @return the string representation of the given 1505 * {@code field} in the given {@code style}, or 1506 * {@code null} if no string representation is 1507 * applicable. 1508 * @exception IllegalArgumentException 1509 * if {@code field} or {@code style} is invalid, 1510 * or if this {@code Calendar} is non-lenient and any 1511 * of the calendar fields have invalid values 1512 * @exception NullPointerException 1513 * if {@code locale} is null 1514 * @since 1.6 1515 */ 1516 public String getDisplayName(int field, int style, Locale locale) { 1517 if (!checkDisplayNameParams(field, style, SHORT, NARROW_FORMAT, locale, 1518 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 1519 return null; 1520 } 1521 1522 // the standalone and narrow styles are supported only through CalendarDataProviders. 1523 if (isStandaloneStyle(style) || isNarrowStyle(style)) { 1524 return CalendarDataUtility.retrieveFieldValueName(getCalendarType(), 1525 field, get(field), 1526 style, locale); 1527 } 1528 1529 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 1530 String[] strings = getFieldStrings(field, style, symbols); 1531 if (strings != null) { 1532 int fieldValue = get(field); 1533 if (fieldValue < strings.length) { 1534 return strings[fieldValue]; 1535 } 1536 } 1537 return null; 1538 } 1539 1540 /** 1541 * Returns a {@code Map} containing all names of the calendar 1542 * {@code field} in the given {@code style} and 1543 * {@code locale} and their corresponding field values. For 1544 * example, if this {@code Calendar} is a {@link 1545 * GregorianCalendar}, the returned map would contain "Jan" to 1546 * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the 1547 * {@linkplain #SHORT short} style in an English locale. 1548 * 1549 * <p>Narrow names may not be unique due to use of single characters, 1550 * such as "S" for Sunday and Saturday. In that case narrow names are not 1551 * included in the returned {@code Map}. 1552 * 1553 * <p>The values of other calendar fields may be taken into 1554 * account to determine a set of display names. For example, if 1555 * this {@code Calendar} is a lunisolar calendar system and 1556 * the year value given by the {@link #YEAR} field has a leap 1557 * month, this method would return month names containing the leap 1558 * month name, and month names are mapped to their values specific 1559 * for the year. 1560 * 1561 * <p>The default implementation supports display names contained in 1562 * a {@link DateFormatSymbols}. For example, if {@code field} 1563 * is {@link #MONTH} and {@code style} is {@link 1564 * #ALL_STYLES}, this method returns a {@code Map} containing 1565 * all strings returned by {@link DateFormatSymbols#getShortMonths()} 1566 * and {@link DateFormatSymbols#getMonths()}. 1567 * 1568 * @param field 1569 * the calendar field for which the display names are returned 1570 * @param style 1571 * the style applied to the string representation; one of {@link 1572 * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 1573 * {@link #LONG_FORMAT} ({@link #LONG}), {@link #LONG_STANDALONE}, 1574 * {@link #NARROW_FORMAT}, or {@link #NARROW_STANDALONE} 1575 * @param locale 1576 * the locale for the display names 1577 * @return a {@code Map} containing all display names in 1578 * {@code style} and {@code locale} and their 1579 * field values, or {@code null} if no display names 1580 * are defined for {@code field} 1581 * @exception IllegalArgumentException 1582 * if {@code field} or {@code style} is invalid, 1583 * or if this {@code Calendar} is non-lenient and any 1584 * of the calendar fields have invalid values 1585 * @exception NullPointerException 1586 * if {@code locale} is null 1587 * @since 1.6 1588 */ 1589 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 1590 if (!checkDisplayNameParams(field, style, ALL_STYLES, NARROW_FORMAT, locale, 1591 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 1592 return null; 1593 } 1594 if (style == ALL_STYLES || isStandaloneStyle(style)) { 1595 return CalendarDataUtility.retrieveFieldValueNames(getCalendarType(), field, style, locale); 1596 } 1597 // SHORT, LONG, or NARROW 1598 return getDisplayNamesImpl(field, style, locale); 1599 } 1600 1601 private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) { 1602 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 1603 String[] strings = getFieldStrings(field, style, symbols); 1604 if (strings != null) { 1605 Map<String,Integer> names = new HashMap<>(); 1606 for (int i = 0; i < strings.length; i++) { 1607 if (strings[i].length() == 0) { 1608 continue; 1609 } 1610 names.put(strings[i], i); 1611 } 1612 return names; 1613 } 1614 return null; 1615 } 1616 1617 boolean checkDisplayNameParams(int field, int style, int minStyle, int maxStyle, 1618 Locale locale, int fieldMask) { 1619 int baseStyle = getBaseStyle(style); // Ignore the standalone mask 1620 if (field < 0 || field >= fields.length || 1621 baseStyle < minStyle || baseStyle > maxStyle) { 1622 throw new IllegalArgumentException(); 1623 } 1624 if (locale == null) { 1625 throw new NullPointerException(); 1626 } 1627 return isFieldSet(fieldMask, field); 1628 } 1629 1630 private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) { 1631 int baseStyle = getBaseStyle(style); // ignore the standalone mask 1632 1633 // DateFormatSymbols doesn't support any narrow names. 1634 if (baseStyle == NARROW_FORMAT) { 1635 return null; 1636 } 1637 1638 String[] strings = null; 1639 switch (field) { 1640 case ERA: 1641 strings = symbols.getEras(); 1642 break; 1643 1644 case MONTH: 1645 strings = (baseStyle == LONG) ? symbols.getMonths() : symbols.getShortMonths(); 1646 break; 1647 1648 case DAY_OF_WEEK: 1649 strings = (baseStyle == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays(); 1650 break; 1651 1652 case AM_PM: 1653 strings = symbols.getAmPmStrings(); 1654 break; 1655 } 1656 return strings; 1657 } 1965 } 1966 if (stamp[MILLISECOND] != UNSET) { 1967 fieldMask |= MILLISECOND_MASK; 1968 } 1969 if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) { 1970 fieldMask |= ZONE_OFFSET_MASK; 1971 } 1972 if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { 1973 fieldMask |= DST_OFFSET_MASK; 1974 } 1975 1976 return fieldMask; 1977 } 1978 1979 int getBaseStyle(int style) { 1980 return style & ~STANDALONE_MASK; 1981 } 1982 1983 boolean isStandaloneStyle(int style) { 1984 return (style & STANDALONE_MASK) != 0; 1985 } 1986 1987 boolean isNarrowStyle(int style) { 1988 return style == NARROW_FORMAT || style == NARROW_STANDALONE; 1989 } 1990 1991 /** 1992 * Returns the pseudo-time-stamp for two fields, given their 1993 * individual pseudo-time-stamps. If either of the fields 1994 * is unset, then the aggregate is unset. Otherwise, the 1995 * aggregate is the later of the two stamps. 1996 */ 1997 private static int aggregateStamp(int stamp_a, int stamp_b) { 1998 if (stamp_a == UNSET || stamp_b == UNSET) { 1999 return UNSET; 2000 } 2001 return (stamp_a > stamp_b) ? stamp_a : stamp_b; 2002 } 2003 2004 /** 2005 * Returns the calendar type of this {@code Calendar}. Calendar types are 2006 * defined by the <em>Unicode Locale Data Markup Language (LDML)</em> 2007 * specification. 2008 * |