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'.
|