< prev index next >

src/java.base/share/classes/java/util/JapaneseImperialCalendar.java

Print this page




  36 import sun.util.calendar.Gregorian;
  37 import sun.util.calendar.LocalGregorianCalendar;
  38 import sun.util.calendar.ZoneInfo;
  39 
  40 /**
  41  * {@code JapaneseImperialCalendar} implements a Japanese
  42  * calendar system in which the imperial era-based year numbering is
  43  * supported from the Meiji era. The following are the eras supported
  44  * by this calendar system.
  45  * <pre>{@code
  46  * ERA value   Era name    Since (in Gregorian)
  47  * ------------------------------------------------------
  48  *     0       N/A         N/A
  49  *     1       Meiji       1868-01-01T00:00:00 local time
  50  *     2       Taisho      1912-07-30T00:00:00 local time
  51  *     3       Showa       1926-12-25T00:00:00 local time
  52  *     4       Heisei      1989-01-08T00:00:00 local time
  53  * ------------------------------------------------------
  54  * }</pre>
  55  *
  56  * <p><code>ERA</code> value 0 specifies the years before Meiji and
  57  * the Gregorian year values are used. Unlike {@link
  58  * GregorianCalendar}, the Julian to Gregorian transition is not
  59  * supported because it doesn't make any sense to the Japanese
  60  * calendar systems used before Meiji. To represent the years before
  61  * Gregorian year 1, 0 and negative values are used. The Japanese
  62  * Imperial rescripts and government decrees don't specify how to deal
  63  * with time differences for applying the era transitions. This
  64  * calendar implementation assumes local time for all transitions.
  65  *
  66  * <p>A new era can be specified using property
  67  * jdk.calendar.japanese.supplemental.era. The new era is added to the
  68  * predefined eras. The syntax of the property is as follows.
  69  * <p><pre>
  70  *   {@code name=<name>,abbr=<abbr>,since=<time['u']>}
  71  * </pre>
  72  * where
  73  * <dl>
  74  * <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed)
  75  * <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed)
  76  * <dt>{@code <time['u']>:}<dd>the start time of the new era represented by
  77  * milliseconds from 1970-01-01T00:00:00 local time or UTC if {@code 'u'} is
  78  * appended to the milliseconds value. (ASCII digits only)
  79  * </dl>
  80  *
  81  * <p>If the given era is invalid, such as the since value before the
  82  * beginning of the last predefined era, the given era will be
  83  * ignored.
  84  *
  85  * <p>The following is an example of the property usage.
  86  * <p><pre>
  87  *   java -Djdk.calendar.japanese.supplemental.era="name=NewEra,abbr=N,since=253374307200000"
  88  * </pre>
  89  * The property specifies an era change to NewEra at 9999-02-11T00:00:00 local time.
  90  *
  91  * @author Masayoshi Okutsu
  92  * @since 1.6
  93  */
  94 class JapaneseImperialCalendar extends Calendar {
  95     /*
  96      * Implementation Notes
  97      *
  98      * This implementation uses
  99      * sun.util.calendar.LocalGregorianCalendar to perform most of the
 100      * calendar calculations.
 101      */
 102 
 103     /**
 104      * The ERA constant designating the era before Meiji.
 105      */
 106     public static final int BEFORE_MEIJI = 0;


 298     /**
 299      * jdate always has a sun.util.calendar.LocalGregorianCalendar.Date instance to
 300      * avoid overhead of creating it for each calculation.
 301      */
 302     private transient LocalGregorianCalendar.Date jdate;
 303 
 304     /**
 305      * Temporary int[2] to get time zone offsets. zoneOffsets[0] gets
 306      * the GMT offset value and zoneOffsets[1] gets the daylight saving
 307      * value.
 308      */
 309     private transient int[] zoneOffsets;
 310 
 311     /**
 312      * Temporary storage for saving original fields[] values in
 313      * non-lenient mode.
 314      */
 315     private transient int[] originalFields;
 316 
 317     /**
 318      * Constructs a <code>JapaneseImperialCalendar</code> based on the current time
 319      * in the given time zone with the given locale.
 320      *
 321      * @param zone the given time zone.
 322      * @param aLocale the given locale.
 323      */
 324     JapaneseImperialCalendar(TimeZone zone, Locale aLocale) {
 325         super(zone, aLocale);
 326         jdate = jcal.newCalendarDate(zone);
 327         setTimeInMillis(System.currentTimeMillis());
 328     }
 329 
 330     /**
 331      * Constructs an "empty" {@code JapaneseImperialCalendar}.
 332      *
 333      * @param zone    the given time zone
 334      * @param aLocale the given locale
 335      * @param flag    the flag requesting an empty instance
 336      */
 337     JapaneseImperialCalendar(TimeZone zone, Locale aLocale, boolean flag) {
 338         super(zone, aLocale);
 339         jdate = jcal.newCalendarDate(zone);
 340     }
 341 
 342     /**
 343      * Returns {@code "japanese"} as the calendar type of this {@code
 344      * JapaneseImperialCalendar}.
 345      *
 346      * @return {@code "japanese"}
 347      */
 348     @Override
 349     public String getCalendarType() {
 350         return "japanese";
 351     }
 352 
 353     /**
 354      * Compares this <code>JapaneseImperialCalendar</code> to the specified
 355      * <code>Object</code>. The result is <code>true</code> if and
 356      * only if the argument is a <code>JapaneseImperialCalendar</code> object
 357      * that represents the same time value (millisecond offset from
 358      * the <a href="Calendar.html#Epoch">Epoch</a>) under the same
 359      * <code>Calendar</code> parameters.
 360      *
 361      * @param obj the object to compare with.
 362      * @return <code>true</code> if this object is equal to <code>obj</code>;
 363      * <code>false</code> otherwise.
 364      * @see Calendar#compareTo(Calendar)
 365      */
 366     @Override
 367     public boolean equals(Object obj) {
 368         return obj instanceof JapaneseImperialCalendar &&
 369             super.equals(obj);
 370     }
 371 
 372     /**
 373      * Generates the hash code for this
 374      * <code>JapaneseImperialCalendar</code> object.
 375      */
 376     @Override
 377     public int hashCode() {
 378         return super.hashCode() ^ jdate.hashCode();
 379     }
 380 
 381     /**
 382      * Adds the specified (signed) amount of time to the given calendar field,
 383      * based on the calendar's rules.
 384      *
 385      * <p><em>Add rule 1</em>. The value of <code>field</code>
 386      * after the call minus the value of <code>field</code> before the
 387      * call is <code>amount</code>, modulo any overflow that has occurred in
 388      * <code>field</code>. Overflow occurs when a field value exceeds its
 389      * range and, as a result, the next larger field is incremented or
 390      * decremented and the field value is adjusted back into its range.</p>
 391      *
 392      * <p><em>Add rule 2</em>. If a smaller field is expected to be
 393      * invariant, but it is impossible for it to be equal to its
 394      * prior value because of changes in its minimum or maximum after
 395      * <code>field</code> is changed, then its value is adjusted to be as close
 396      * as possible to its expected value. A smaller field represents a
 397      * smaller unit of time. <code>HOUR</code> is a smaller field than
 398      * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
 399      * that are not expected to be invariant. The calendar system
 400      * determines what fields are expected to be invariant.</p>
 401      *
 402      * @param field the calendar field.
 403      * @param amount the amount of date or time to be added to the field.
 404      * @exception IllegalArgumentException if <code>field</code> is
 405      * <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or unknown,
 406      * or if any calendar fields have out-of-range values in
 407      * non-lenient mode.
 408      */
 409     @Override
 410     public void add(int field, int amount) {
 411         // If amount == 0, do nothing even the given field is out of
 412         // range. This is tested by JCK.
 413         if (amount == 0) {
 414             return;   // Do nothing!
 415         }
 416 
 417         if (field < 0 || field >= ZONE_OFFSET) {
 418             throw new IllegalArgumentException();
 419         }
 420 
 421         // Sync the time and calendar fields.
 422         complete();
 423 
 424         if (field == YEAR) {
 425             LocalGregorianCalendar.Date d = (LocalGregorianCalendar.Date) jdate.clone();


 531                 if (fd2 != fd) {
 532                     setTimeInMillis(time - zoneOffset);
 533                 }
 534             }
 535         }
 536     }
 537 
 538     @Override
 539     public void roll(int field, boolean up) {
 540         roll(field, up ? +1 : -1);
 541     }
 542 
 543     /**
 544      * Adds a signed amount to the specified calendar field without changing larger fields.
 545      * A negative roll amount means to subtract from field without changing
 546      * larger fields. If the specified amount is 0, this method performs nothing.
 547      *
 548      * <p>This method calls {@link #complete()} before adding the
 549      * amount so that all the calendar fields are normalized. If there
 550      * is any calendar field having an out-of-range value in non-lenient mode, then an
 551      * <code>IllegalArgumentException</code> is thrown.
 552      *
 553      * @param field the calendar field.
 554      * @param amount the signed amount to add to <code>field</code>.
 555      * @exception IllegalArgumentException if <code>field</code> is
 556      * <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or unknown,
 557      * or if any calendar fields have out-of-range values in
 558      * non-lenient mode.
 559      * @see #roll(int,boolean)
 560      * @see #add(int,int)
 561      * @see #set(int,int)
 562      */
 563     @Override
 564     public void roll(int field, int amount) {
 565         // If amount == 0, do nothing even the given field is out of
 566         // range. This is tested by JCK.
 567         if (amount == 0) {
 568             return;
 569         }
 570 
 571         if (field < 0 || field >= ZONE_OFFSET) {
 572             throw new IllegalArgumentException();
 573         }
 574 
 575         // Sync the time and calendar fields.
 576         complete();


1038                 if (size < eras.length) {
1039                     int baseStyle = getBaseStyle(style);
1040                     for (int i = size; i < eras.length; i++) {
1041                         Era era = eras[i];
1042                         if (baseStyle == ALL_STYLES || baseStyle == SHORT
1043                                 || baseStyle == NARROW_FORMAT) {
1044                             names.put(era.getAbbreviation(), i);
1045                         }
1046                         if (baseStyle == ALL_STYLES || baseStyle == LONG) {
1047                             names.put(era.getName(), i);
1048                         }
1049                     }
1050                 }
1051             }
1052         }
1053         return names;
1054     }
1055 
1056     /**
1057      * Returns the minimum value for the given calendar field of this
1058      * <code>Calendar</code> instance. The minimum value is
1059      * defined as the smallest value returned by the {@link
1060      * Calendar#get(int) get} method for any possible time value,
1061      * taking into consideration the current values of the
1062      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1063      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1064      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1065      *
1066      * @param field the calendar field.
1067      * @return the minimum value for the given calendar field.
1068      * @see #getMaximum(int)
1069      * @see #getGreatestMinimum(int)
1070      * @see #getLeastMaximum(int)
1071      * @see #getActualMinimum(int)
1072      * @see #getActualMaximum(int)
1073      */
1074     public int getMinimum(int field) {
1075         return MIN_VALUES[field];
1076     }
1077 
1078     /**
1079      * Returns the maximum value for the given calendar field of this
1080      * <code>GregorianCalendar</code> instance. The maximum value is
1081      * defined as the largest value returned by the {@link
1082      * Calendar#get(int) get} method for any possible time value,
1083      * taking into consideration the current values of the
1084      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1085      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1086      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1087      *
1088      * @param field the calendar field.
1089      * @return the maximum value for the given calendar field.
1090      * @see #getMinimum(int)
1091      * @see #getGreatestMinimum(int)
1092      * @see #getLeastMaximum(int)
1093      * @see #getActualMinimum(int)
1094      * @see #getActualMaximum(int)
1095      */
1096     public int getMaximum(int field) {
1097         switch (field) {
1098         case YEAR:
1099             {
1100                 // The value should depend on the time zone of this calendar.
1101                 LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MAX_VALUE,
1102                                                                      getZone());
1103                 return Math.max(LEAST_MAX_VALUES[YEAR], d.getYear());
1104             }
1105         }
1106         return MAX_VALUES[field];
1107     }
1108 
1109     /**
1110      * Returns the highest minimum value for the given calendar field
1111      * of this <code>GregorianCalendar</code> instance. The highest
1112      * minimum value is defined as the largest value returned by
1113      * {@link #getActualMinimum(int)} for any possible time value,
1114      * taking into consideration the current values of the
1115      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1116      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1117      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1118      *
1119      * @param field the calendar field.
1120      * @return the highest minimum value for the given calendar field.
1121      * @see #getMinimum(int)
1122      * @see #getMaximum(int)
1123      * @see #getLeastMaximum(int)
1124      * @see #getActualMinimum(int)
1125      * @see #getActualMaximum(int)
1126      */
1127     public int getGreatestMinimum(int field) {
1128         return field == YEAR ? 1 : MIN_VALUES[field];
1129     }
1130 
1131     /**
1132      * Returns the lowest maximum value for the given calendar field
1133      * of this <code>GregorianCalendar</code> instance. The lowest
1134      * maximum value is defined as the smallest value returned by
1135      * {@link #getActualMaximum(int)} for any possible time value,
1136      * taking into consideration the current values of the
1137      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1138      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1139      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1140      *
1141      * @param field the calendar field
1142      * @return the lowest maximum value for the given calendar field.
1143      * @see #getMinimum(int)
1144      * @see #getMaximum(int)
1145      * @see #getGreatestMinimum(int)
1146      * @see #getActualMinimum(int)
1147      * @see #getActualMaximum(int)
1148      */
1149     public int getLeastMaximum(int field) {
1150         switch (field) {
1151         case YEAR:
1152             {
1153                 return Math.min(LEAST_MAX_VALUES[YEAR], getMaximum(YEAR));
1154             }
1155         }
1156         return LEAST_MAX_VALUES[field];
1157     }
1158 
1159     /**
1160      * Returns the minimum value that this calendar field could have,
1161      * taking into consideration the given time value and the current
1162      * values of the
1163      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1164      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1165      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1166      *
1167      * @param field the calendar field
1168      * @return the minimum of the given field for the time value of
1169      * this <code>JapaneseImperialCalendar</code>
1170      * @see #getMinimum(int)
1171      * @see #getMaximum(int)
1172      * @see #getGreatestMinimum(int)
1173      * @see #getLeastMaximum(int)
1174      * @see #getActualMaximum(int)
1175      */
1176     public int getActualMinimum(int field) {
1177         if (!isFieldSet(YEAR_MASK|MONTH_MASK|WEEK_OF_YEAR_MASK, field)) {
1178             return getMinimum(field);
1179         }
1180 
1181         int value = 0;
1182         JapaneseImperialCalendar jc = getNormalizedCalendar();
1183         // Get a local date which includes time of day and time zone,
1184         // which are missing in jc.jdate.
1185         LocalGregorianCalendar.Date jd = jcal.getCalendarDate(jc.getTimeInMillis(),
1186                                                               getZone());
1187         int eraIndex = getEraIndex(jd);
1188         switch (field) {
1189         case YEAR:


1252                 if ((day1 < jan1) ||
1253                     (day1 == jan1 &&
1254                      jd.getTimeOfDay() < d.getTimeOfDay())) {
1255                     value++;
1256                 }
1257             }
1258             break;
1259         }
1260         return value;
1261     }
1262 
1263     /**
1264      * Returns the maximum value that this calendar field could have,
1265      * taking into consideration the given time value and the current
1266      * values of the
1267      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1268      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1269      * and
1270      * {@link Calendar#getTimeZone() getTimeZone} methods.
1271      * For example, if the date of this instance is Heisei 16February 1,
1272      * the actual maximum value of the <code>DAY_OF_MONTH</code> field
1273      * is 29 because Heisei 16 is a leap year, and if the date of this
1274      * instance is Heisei 17 February 1, it's 28.
1275      *
1276      * @param field the calendar field
1277      * @return the maximum of the given field for the time value of
1278      * this <code>JapaneseImperialCalendar</code>
1279      * @see #getMinimum(int)
1280      * @see #getMaximum(int)
1281      * @see #getGreatestMinimum(int)
1282      * @see #getLeastMaximum(int)
1283      * @see #getActualMinimum(int)
1284      */
1285     public int getActualMaximum(int field) {
1286         final int fieldsForFixedMax = ERA_MASK|DAY_OF_WEEK_MASK|HOUR_MASK|AM_PM_MASK|
1287             HOUR_OF_DAY_MASK|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK|
1288             ZONE_OFFSET_MASK|DST_OFFSET_MASK;
1289         if ((fieldsForFixedMax & (1<<field)) != 0) {
1290             return getMaximum(field);
1291         }
1292 
1293         JapaneseImperialCalendar jc = getNormalizedCalendar();
1294         LocalGregorianCalendar.Date date = jc.jdate;
1295         int normalizedYear = date.getNormalizedYear();
1296 
1297         int value = -1;
1298         switch (field) {


1541         return zone;
1542     }
1543 
1544     public void setTimeZone(TimeZone zone) {
1545         super.setTimeZone(zone);
1546         // To share the zone by the CalendarDate
1547         jdate.setZone(zone);
1548     }
1549 
1550     /**
1551      * The fixed date corresponding to jdate. If the value is
1552      * Long.MIN_VALUE, the fixed date value is unknown.
1553      */
1554     transient private long cachedFixedDate = Long.MIN_VALUE;
1555 
1556     /**
1557      * Converts the time value (millisecond offset from the <a
1558      * href="Calendar.html#Epoch">Epoch</a>) to calendar field values.
1559      * The time is <em>not</em>
1560      * recomputed first; to recompute the time, then the fields, call the
1561      * <code>complete</code> method.
1562      *
1563      * @see Calendar#complete
1564      */
1565     protected void computeFields() {
1566         int mask = 0;
1567         if (isPartiallyNormalized()) {
1568             // Determine which calendar fields need to be computed.
1569             mask = getSetStateFields();
1570             int fieldMask = ~mask & ALL_FIELDS;
1571             if (fieldMask != 0 || cachedFixedDate == Long.MIN_VALUE) {
1572                 mask |= computeFields(fieldMask,
1573                                       mask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK));
1574                 assert mask == ALL_FIELDS;
1575             }
1576         } else {
1577             // Specify all fields
1578             mask = ALL_FIELDS;
1579             computeFields(mask, 0);
1580         }
1581         // After computing all the fields, set the field state to `COMPUTED'.




  36 import sun.util.calendar.Gregorian;
  37 import sun.util.calendar.LocalGregorianCalendar;
  38 import sun.util.calendar.ZoneInfo;
  39 
  40 /**
  41  * {@code JapaneseImperialCalendar} implements a Japanese
  42  * calendar system in which the imperial era-based year numbering is
  43  * supported from the Meiji era. The following are the eras supported
  44  * by this calendar system.
  45  * <pre>{@code
  46  * ERA value   Era name    Since (in Gregorian)
  47  * ------------------------------------------------------
  48  *     0       N/A         N/A
  49  *     1       Meiji       1868-01-01T00:00:00 local time
  50  *     2       Taisho      1912-07-30T00:00:00 local time
  51  *     3       Showa       1926-12-25T00:00:00 local time
  52  *     4       Heisei      1989-01-08T00:00:00 local time
  53  * ------------------------------------------------------
  54  * }</pre>
  55  *
  56  * <p>{@code ERA} value 0 specifies the years before Meiji and
  57  * the Gregorian year values are used. Unlike {@link
  58  * GregorianCalendar}, the Julian to Gregorian transition is not
  59  * supported because it doesn't make any sense to the Japanese
  60  * calendar systems used before Meiji. To represent the years before
  61  * Gregorian year 1, 0 and negative values are used. The Japanese
  62  * Imperial rescripts and government decrees don't specify how to deal
  63  * with time differences for applying the era transitions. This
  64  * calendar implementation assumes local time for all transitions.
  65  *
  66  * <p>A new era can be specified using property
  67  * jdk.calendar.japanese.supplemental.era. The new era is added to the
  68  * predefined eras. The syntax of the property is as follows.
  69  * <pre>
  70  *   {@code name=<name>,abbr=<abbr>,since=<time['u']>}
  71  * </pre>
  72  * where
  73  * <dl>
  74  * <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed)
  75  * <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed)
  76  * <dt>{@code <time['u']>:}<dd>the start time of the new era represented by
  77  * milliseconds from 1970-01-01T00:00:00 local time or UTC if {@code 'u'} is
  78  * appended to the milliseconds value. (ASCII digits only)
  79  * </dl>
  80  *
  81  * <p>If the given era is invalid, such as the since value before the
  82  * beginning of the last predefined era, the given era will be
  83  * ignored.
  84  *
  85  * <p>The following is an example of the property usage.
  86  * <pre>
  87  *   java -Djdk.calendar.japanese.supplemental.era="name=NewEra,abbr=N,since=253374307200000"
  88  * </pre>
  89  * The property specifies an era change to NewEra at 9999-02-11T00:00:00 local time.
  90  *
  91  * @author Masayoshi Okutsu
  92  * @since 1.6
  93  */
  94 class JapaneseImperialCalendar extends Calendar {
  95     /*
  96      * Implementation Notes
  97      *
  98      * This implementation uses
  99      * sun.util.calendar.LocalGregorianCalendar to perform most of the
 100      * calendar calculations.
 101      */
 102 
 103     /**
 104      * The ERA constant designating the era before Meiji.
 105      */
 106     public static final int BEFORE_MEIJI = 0;


 298     /**
 299      * jdate always has a sun.util.calendar.LocalGregorianCalendar.Date instance to
 300      * avoid overhead of creating it for each calculation.
 301      */
 302     private transient LocalGregorianCalendar.Date jdate;
 303 
 304     /**
 305      * Temporary int[2] to get time zone offsets. zoneOffsets[0] gets
 306      * the GMT offset value and zoneOffsets[1] gets the daylight saving
 307      * value.
 308      */
 309     private transient int[] zoneOffsets;
 310 
 311     /**
 312      * Temporary storage for saving original fields[] values in
 313      * non-lenient mode.
 314      */
 315     private transient int[] originalFields;
 316 
 317     /**
 318      * Constructs a {@code JapaneseImperialCalendar} based on the current time
 319      * in the given time zone with the given locale.
 320      *
 321      * @param zone the given time zone.
 322      * @param aLocale the given locale.
 323      */
 324     JapaneseImperialCalendar(TimeZone zone, Locale aLocale) {
 325         super(zone, aLocale);
 326         jdate = jcal.newCalendarDate(zone);
 327         setTimeInMillis(System.currentTimeMillis());
 328     }
 329 
 330     /**
 331      * Constructs an "empty" {@code JapaneseImperialCalendar}.
 332      *
 333      * @param zone    the given time zone
 334      * @param aLocale the given locale
 335      * @param flag    the flag requesting an empty instance
 336      */
 337     JapaneseImperialCalendar(TimeZone zone, Locale aLocale, boolean flag) {
 338         super(zone, aLocale);
 339         jdate = jcal.newCalendarDate(zone);
 340     }
 341 
 342     /**
 343      * Returns {@code "japanese"} as the calendar type of this {@code
 344      * JapaneseImperialCalendar}.
 345      *
 346      * @return {@code "japanese"}
 347      */
 348     @Override
 349     public String getCalendarType() {
 350         return "japanese";
 351     }
 352 
 353     /**
 354      * Compares this {@code JapaneseImperialCalendar} to the specified
 355      * {@code Object}. The result is {@code true} if and
 356      * only if the argument is a {@code JapaneseImperialCalendar} object
 357      * that represents the same time value (millisecond offset from
 358      * the <a href="Calendar.html#Epoch">Epoch</a>) under the same
 359      * {@code Calendar} parameters.
 360      *
 361      * @param obj the object to compare with.
 362      * @return {@code true} if this object is equal to {@code obj};
 363      * {@code false} otherwise.
 364      * @see Calendar#compareTo(Calendar)
 365      */
 366     @Override
 367     public boolean equals(Object obj) {
 368         return obj instanceof JapaneseImperialCalendar &&
 369             super.equals(obj);
 370     }
 371 
 372     /**
 373      * Generates the hash code for this
 374      * {@code JapaneseImperialCalendar} object.
 375      */
 376     @Override
 377     public int hashCode() {
 378         return super.hashCode() ^ jdate.hashCode();
 379     }
 380 
 381     /**
 382      * Adds the specified (signed) amount of time to the given calendar field,
 383      * based on the calendar's rules.
 384      *
 385      * <p><em>Add rule 1</em>. The value of {@code field}
 386      * after the call minus the value of {@code field} before the
 387      * call is {@code amount}, modulo any overflow that has occurred in
 388      * {@code field}. Overflow occurs when a field value exceeds its
 389      * range and, as a result, the next larger field is incremented or
 390      * decremented and the field value is adjusted back into its range.</p>
 391      *
 392      * <p><em>Add rule 2</em>. If a smaller field is expected to be
 393      * invariant, but it is impossible for it to be equal to its
 394      * prior value because of changes in its minimum or maximum after
 395      * {@code field} is changed, then its value is adjusted to be as close
 396      * as possible to its expected value. A smaller field represents a
 397      * smaller unit of time. {@code HOUR} is a smaller field than
 398      * {@code DAY_OF_MONTH}. No adjustment is made to smaller fields
 399      * that are not expected to be invariant. The calendar system
 400      * determines what fields are expected to be invariant.</p>
 401      *
 402      * @param field the calendar field.
 403      * @param amount the amount of date or time to be added to the field.
 404      * @exception IllegalArgumentException if {@code field} is
 405      * {@code ZONE_OFFSET}, {@code DST_OFFSET}, or unknown,
 406      * or if any calendar fields have out-of-range values in
 407      * non-lenient mode.
 408      */
 409     @Override
 410     public void add(int field, int amount) {
 411         // If amount == 0, do nothing even the given field is out of
 412         // range. This is tested by JCK.
 413         if (amount == 0) {
 414             return;   // Do nothing!
 415         }
 416 
 417         if (field < 0 || field >= ZONE_OFFSET) {
 418             throw new IllegalArgumentException();
 419         }
 420 
 421         // Sync the time and calendar fields.
 422         complete();
 423 
 424         if (field == YEAR) {
 425             LocalGregorianCalendar.Date d = (LocalGregorianCalendar.Date) jdate.clone();


 531                 if (fd2 != fd) {
 532                     setTimeInMillis(time - zoneOffset);
 533                 }
 534             }
 535         }
 536     }
 537 
 538     @Override
 539     public void roll(int field, boolean up) {
 540         roll(field, up ? +1 : -1);
 541     }
 542 
 543     /**
 544      * Adds a signed amount to the specified calendar field without changing larger fields.
 545      * A negative roll amount means to subtract from field without changing
 546      * larger fields. If the specified amount is 0, this method performs nothing.
 547      *
 548      * <p>This method calls {@link #complete()} before adding the
 549      * amount so that all the calendar fields are normalized. If there
 550      * is any calendar field having an out-of-range value in non-lenient mode, then an
 551      * {@code IllegalArgumentException} is thrown.
 552      *
 553      * @param field the calendar field.
 554      * @param amount the signed amount to add to {@code field}.
 555      * @exception IllegalArgumentException if {@code field} is
 556      * {@code ZONE_OFFSET}, {@code DST_OFFSET}, or unknown,
 557      * or if any calendar fields have out-of-range values in
 558      * non-lenient mode.
 559      * @see #roll(int,boolean)
 560      * @see #add(int,int)
 561      * @see #set(int,int)
 562      */
 563     @Override
 564     public void roll(int field, int amount) {
 565         // If amount == 0, do nothing even the given field is out of
 566         // range. This is tested by JCK.
 567         if (amount == 0) {
 568             return;
 569         }
 570 
 571         if (field < 0 || field >= ZONE_OFFSET) {
 572             throw new IllegalArgumentException();
 573         }
 574 
 575         // Sync the time and calendar fields.
 576         complete();


1038                 if (size < eras.length) {
1039                     int baseStyle = getBaseStyle(style);
1040                     for (int i = size; i < eras.length; i++) {
1041                         Era era = eras[i];
1042                         if (baseStyle == ALL_STYLES || baseStyle == SHORT
1043                                 || baseStyle == NARROW_FORMAT) {
1044                             names.put(era.getAbbreviation(), i);
1045                         }
1046                         if (baseStyle == ALL_STYLES || baseStyle == LONG) {
1047                             names.put(era.getName(), i);
1048                         }
1049                     }
1050                 }
1051             }
1052         }
1053         return names;
1054     }
1055 
1056     /**
1057      * Returns the minimum value for the given calendar field of this
1058      * {@code Calendar} instance. The minimum value is
1059      * defined as the smallest value returned by the {@link
1060      * Calendar#get(int) get} method for any possible time value,
1061      * taking into consideration the current values of the
1062      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1063      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1064      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1065      *
1066      * @param field the calendar field.
1067      * @return the minimum value for the given calendar field.
1068      * @see #getMaximum(int)
1069      * @see #getGreatestMinimum(int)
1070      * @see #getLeastMaximum(int)
1071      * @see #getActualMinimum(int)
1072      * @see #getActualMaximum(int)
1073      */
1074     public int getMinimum(int field) {
1075         return MIN_VALUES[field];
1076     }
1077 
1078     /**
1079      * Returns the maximum value for the given calendar field of this
1080      * {@code GregorianCalendar} instance. The maximum value is
1081      * defined as the largest value returned by the {@link
1082      * Calendar#get(int) get} method for any possible time value,
1083      * taking into consideration the current values of the
1084      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1085      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1086      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1087      *
1088      * @param field the calendar field.
1089      * @return the maximum value for the given calendar field.
1090      * @see #getMinimum(int)
1091      * @see #getGreatestMinimum(int)
1092      * @see #getLeastMaximum(int)
1093      * @see #getActualMinimum(int)
1094      * @see #getActualMaximum(int)
1095      */
1096     public int getMaximum(int field) {
1097         switch (field) {
1098         case YEAR:
1099             {
1100                 // The value should depend on the time zone of this calendar.
1101                 LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MAX_VALUE,
1102                                                                      getZone());
1103                 return Math.max(LEAST_MAX_VALUES[YEAR], d.getYear());
1104             }
1105         }
1106         return MAX_VALUES[field];
1107     }
1108 
1109     /**
1110      * Returns the highest minimum value for the given calendar field
1111      * of this {@code GregorianCalendar} instance. The highest
1112      * minimum value is defined as the largest value returned by
1113      * {@link #getActualMinimum(int)} for any possible time value,
1114      * taking into consideration the current values of the
1115      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1116      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1117      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1118      *
1119      * @param field the calendar field.
1120      * @return the highest minimum value for the given calendar field.
1121      * @see #getMinimum(int)
1122      * @see #getMaximum(int)
1123      * @see #getLeastMaximum(int)
1124      * @see #getActualMinimum(int)
1125      * @see #getActualMaximum(int)
1126      */
1127     public int getGreatestMinimum(int field) {
1128         return field == YEAR ? 1 : MIN_VALUES[field];
1129     }
1130 
1131     /**
1132      * Returns the lowest maximum value for the given calendar field
1133      * of this {@code GregorianCalendar} instance. The lowest
1134      * maximum value is defined as the smallest value returned by
1135      * {@link #getActualMaximum(int)} for any possible time value,
1136      * taking into consideration the current values of the
1137      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1138      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1139      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1140      *
1141      * @param field the calendar field
1142      * @return the lowest maximum value for the given calendar field.
1143      * @see #getMinimum(int)
1144      * @see #getMaximum(int)
1145      * @see #getGreatestMinimum(int)
1146      * @see #getActualMinimum(int)
1147      * @see #getActualMaximum(int)
1148      */
1149     public int getLeastMaximum(int field) {
1150         switch (field) {
1151         case YEAR:
1152             {
1153                 return Math.min(LEAST_MAX_VALUES[YEAR], getMaximum(YEAR));
1154             }
1155         }
1156         return LEAST_MAX_VALUES[field];
1157     }
1158 
1159     /**
1160      * Returns the minimum value that this calendar field could have,
1161      * taking into consideration the given time value and the current
1162      * values of the
1163      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1164      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1165      * and {@link Calendar#getTimeZone() getTimeZone} methods.
1166      *
1167      * @param field the calendar field
1168      * @return the minimum of the given field for the time value of
1169      * this {@code JapaneseImperialCalendar}
1170      * @see #getMinimum(int)
1171      * @see #getMaximum(int)
1172      * @see #getGreatestMinimum(int)
1173      * @see #getLeastMaximum(int)
1174      * @see #getActualMaximum(int)
1175      */
1176     public int getActualMinimum(int field) {
1177         if (!isFieldSet(YEAR_MASK|MONTH_MASK|WEEK_OF_YEAR_MASK, field)) {
1178             return getMinimum(field);
1179         }
1180 
1181         int value = 0;
1182         JapaneseImperialCalendar jc = getNormalizedCalendar();
1183         // Get a local date which includes time of day and time zone,
1184         // which are missing in jc.jdate.
1185         LocalGregorianCalendar.Date jd = jcal.getCalendarDate(jc.getTimeInMillis(),
1186                                                               getZone());
1187         int eraIndex = getEraIndex(jd);
1188         switch (field) {
1189         case YEAR:


1252                 if ((day1 < jan1) ||
1253                     (day1 == jan1 &&
1254                      jd.getTimeOfDay() < d.getTimeOfDay())) {
1255                     value++;
1256                 }
1257             }
1258             break;
1259         }
1260         return value;
1261     }
1262 
1263     /**
1264      * Returns the maximum value that this calendar field could have,
1265      * taking into consideration the given time value and the current
1266      * values of the
1267      * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1268      * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1269      * and
1270      * {@link Calendar#getTimeZone() getTimeZone} methods.
1271      * For example, if the date of this instance is Heisei 16February 1,
1272      * the actual maximum value of the {@code DAY_OF_MONTH} field
1273      * is 29 because Heisei 16 is a leap year, and if the date of this
1274      * instance is Heisei 17 February 1, it's 28.
1275      *
1276      * @param field the calendar field
1277      * @return the maximum of the given field for the time value of
1278      * this {@code JapaneseImperialCalendar}
1279      * @see #getMinimum(int)
1280      * @see #getMaximum(int)
1281      * @see #getGreatestMinimum(int)
1282      * @see #getLeastMaximum(int)
1283      * @see #getActualMinimum(int)
1284      */
1285     public int getActualMaximum(int field) {
1286         final int fieldsForFixedMax = ERA_MASK|DAY_OF_WEEK_MASK|HOUR_MASK|AM_PM_MASK|
1287             HOUR_OF_DAY_MASK|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK|
1288             ZONE_OFFSET_MASK|DST_OFFSET_MASK;
1289         if ((fieldsForFixedMax & (1<<field)) != 0) {
1290             return getMaximum(field);
1291         }
1292 
1293         JapaneseImperialCalendar jc = getNormalizedCalendar();
1294         LocalGregorianCalendar.Date date = jc.jdate;
1295         int normalizedYear = date.getNormalizedYear();
1296 
1297         int value = -1;
1298         switch (field) {


1541         return zone;
1542     }
1543 
1544     public void setTimeZone(TimeZone zone) {
1545         super.setTimeZone(zone);
1546         // To share the zone by the CalendarDate
1547         jdate.setZone(zone);
1548     }
1549 
1550     /**
1551      * The fixed date corresponding to jdate. If the value is
1552      * Long.MIN_VALUE, the fixed date value is unknown.
1553      */
1554     transient private long cachedFixedDate = Long.MIN_VALUE;
1555 
1556     /**
1557      * Converts the time value (millisecond offset from the <a
1558      * href="Calendar.html#Epoch">Epoch</a>) to calendar field values.
1559      * The time is <em>not</em>
1560      * recomputed first; to recompute the time, then the fields, call the
1561      * {@code complete} method.
1562      *
1563      * @see Calendar#complete
1564      */
1565     protected void computeFields() {
1566         int mask = 0;
1567         if (isPartiallyNormalized()) {
1568             // Determine which calendar fields need to be computed.
1569             mask = getSetStateFields();
1570             int fieldMask = ~mask & ALL_FIELDS;
1571             if (fieldMask != 0 || cachedFixedDate == Long.MIN_VALUE) {
1572                 mask |= computeFields(fieldMask,
1573                                       mask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK));
1574                 assert mask == ALL_FIELDS;
1575             }
1576         } else {
1577             // Specify all fields
1578             mask = ALL_FIELDS;
1579             computeFields(mask, 0);
1580         }
1581         // After computing all the fields, set the field state to `COMPUTED'.


< prev index next >