JapaneseImperialCalendarpublic class JapaneseImperialCalendar extends Calendar JapaneseImperialCalendar implements a Japanese
calendar system in which the imperial era-based year numbering is
supported from the Meiji era. The following are the eras supported
by this calendar system.
ERA value Era name Since (in Gregorian)
------------------------------------------------------
0 N/A N/A
1 Meiji 1868-01-01 midnight local time
2 Taisho 1912-07-30 midnight local time
3 Showa 1926-12-25 midnight local time
4 Heisei 1989-01-08 midnight local time
------------------------------------------------------
ERA value 0 specifies the years before Meiji and
the Gregorian year values are used. Unlike {@link
GregorianCalendar}, the Julian to Gregorian transition is not
supported because it doesn't make any sense to the Japanese
calendar systems used before Meiji. To represent the years before
Gregorian year 1, 0 and negative values are used. The Japanese
Imperial rescripts and government decrees don't specify how to deal
with time differences for applying the era transitions. This
calendar implementation assumes local time for all transitions.
|
Fields Summary |
---|
public static final int | BEFORE_MEIJIThe ERA constant designating the era before Meiji. | public static final int | MEIJIThe ERA constant designating the Meiji era. | public static final int | TAISHOThe ERA constant designating the Taisho era. | public static final int | SHOWAThe ERA constant designating the Showa era. | public static final int | HEISEIThe ERA constant designating the Heisei era. | private static final int | EPOCH_OFFSET | private static final int | EPOCH_YEAR | private static final int | ONE_SECOND | private static final int | ONE_MINUTE | private static final int | ONE_HOUR | private static final long | ONE_DAY | private static final long | ONE_WEEK | private static final LocalGregorianCalendar | jcal | private static final Gregorian | gcal | private static final Era | BEFORE_MEIJI_ERA | private static final Era[] | eras | private static final long[] | sinceFixedDates | static final int[] | MIN_VALUES | static final int[] | LEAST_MAX_VALUES | static final int[] | MAX_VALUES | private static final long | serialVersionUID | private transient LocalGregorianCalendar$Date | jdatejdate always has a sun.util.calendar.LocalGregorianCalendar.Date instance to
avoid overhead of creating it for each calculation. | private transient int[] | zoneOffsetsTemporary int[2] to get time zone offsets. zoneOffsets[0] gets
the GMT offset value and zoneOffsets[1] gets the daylight saving
value. | private transient int[] | originalFieldsTemporary storage for saving original fields[] values in
non-lenient mode. | private transient long | cachedFixedDateThe fixed date corresponding to jdate. If the value is
Long.MIN_VALUE, the fixed date value is unknown. |
Constructors Summary |
---|
public JapaneseImperialCalendar(TimeZone zone, Locale aLocale)Constructs a JapaneseImperialCalendar based on the current time
in the given time zone with the given locale.
super(zone, aLocale);
jdate = jcal.newCalendarDate(zone);
setTimeInMillis(System.currentTimeMillis());
|
Methods Summary |
---|
private final int | actualMonthLength()
int length = jcal.getMonthLength(jdate);
int eraIndex = getTransitionEraIndex(jdate);
if (eraIndex == -1) {
long transitionFixedDate = sinceFixedDates[eraIndex];
CalendarDate d = eras[eraIndex].getSinceDate();
if (transitionFixedDate <= cachedFixedDate) {
length -= d.getDayOfMonth() - 1;
} else {
length = d.getDayOfMonth() - 1;
}
}
return length;
| public void | add(int field, int amount)Adds the specified (signed) amount of time to the given calendar field,
based on the calendar's rules.
Add rule 1. The value of field
after the call minus the value of field before the
call is amount , modulo any overflow that has occurred in
field . Overflow occurs when a field value exceeds its
range and, as a result, the next larger field is incremented or
decremented and the field value is adjusted back into its range.
Add rule 2. If a smaller field is expected to be
invariant, but it is impossible for it to be equal to its
prior value because of changes in its minimum or maximum after
field is changed, then its value is adjusted to be as close
as possible to its expected value. A smaller field represents a
smaller unit of time. HOUR is a smaller field than
DAY_OF_MONTH . No adjustment is made to smaller fields
that are not expected to be invariant. The calendar system
determines what fields are expected to be invariant.
// If amount == 0, do nothing even the given field is out of
// range. This is tested by JCK.
if (amount == 0) {
return; // Do nothing!
}
if (field < 0 || field >= ZONE_OFFSET) {
throw new IllegalArgumentException();
}
// Sync the time and calendar fields.
complete();
if (field == YEAR) {
LocalGregorianCalendar.Date d = (LocalGregorianCalendar.Date) jdate.clone();
d.addYear(amount);
pinDayOfMonth(d);
set(ERA, getEraIndex(d));
set(YEAR, d.getYear());
set(MONTH, d.getMonth() - 1);
set(DAY_OF_MONTH, d.getDayOfMonth());
} else if (field == MONTH) {
LocalGregorianCalendar.Date d = (LocalGregorianCalendar.Date) jdate.clone();
d.addMonth(amount);
pinDayOfMonth(d);
set(ERA, getEraIndex(d));
set(YEAR, d.getYear());
set(MONTH, d.getMonth() - 1);
set(DAY_OF_MONTH, d.getDayOfMonth());
} else if (field == ERA) {
int era = internalGet(ERA) + amount;
if (era < 0) {
era = 0;
} else if (era > eras.length - 1) {
era = eras.length - 1;
}
set(ERA, era);
} else {
long delta = amount;
long timeOfDay = 0;
switch (field) {
// Handle the time fields here. Convert the given
// amount to milliseconds and call setTimeInMillis.
case HOUR:
case HOUR_OF_DAY:
delta *= 60 * 60 * 1000; // hours to milliseconds
break;
case MINUTE:
delta *= 60 * 1000; // minutes to milliseconds
break;
case SECOND:
delta *= 1000; // seconds to milliseconds
break;
case MILLISECOND:
break;
// Handle week, day and AM_PM fields which involves
// time zone offset change adjustment. Convert the
// given amount to the number of days.
case WEEK_OF_YEAR:
case WEEK_OF_MONTH:
case DAY_OF_WEEK_IN_MONTH:
delta *= 7;
break;
case DAY_OF_MONTH: // synonym of DATE
case DAY_OF_YEAR:
case DAY_OF_WEEK:
break;
case AM_PM:
// Convert the amount to the number of days (delta)
// and +12 or -12 hours (timeOfDay).
delta = amount / 2;
timeOfDay = 12 * (amount % 2);
break;
}
// The time fields don't require time zone offset change
// adjustment.
if (field >= HOUR) {
setTimeInMillis(time + delta);
return;
}
// The rest of the fields (week, day or AM_PM fields)
// require time zone offset (both GMT and DST) change
// adjustment.
// Translate the current time to the fixed date and time
// of the day.
long fd = cachedFixedDate;
timeOfDay += internalGet(HOUR_OF_DAY);
timeOfDay *= 60;
timeOfDay += internalGet(MINUTE);
timeOfDay *= 60;
timeOfDay += internalGet(SECOND);
timeOfDay *= 1000;
timeOfDay += internalGet(MILLISECOND);
if (timeOfDay >= ONE_DAY) {
fd++;
timeOfDay -= ONE_DAY;
} else if (timeOfDay < 0) {
fd--;
timeOfDay += ONE_DAY;
}
fd += delta; // fd is the expected fixed date after the calculation
int zoneOffset = internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET);
setTimeInMillis((fd - EPOCH_OFFSET) * ONE_DAY + timeOfDay - zoneOffset);
zoneOffset -= internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET);
// If the time zone offset has changed, then adjust the difference.
if (zoneOffset != 0) {
setTimeInMillis(time + zoneOffset);
long fd2 = cachedFixedDate;
// If the adjustment has changed the date, then take
// the previous one.
if (fd2 != fd) {
setTimeInMillis(time - zoneOffset);
}
}
}
| public java.lang.Object | clone()
JapaneseImperialCalendar other = (JapaneseImperialCalendar) super.clone();
other.jdate = (LocalGregorianCalendar.Date) jdate.clone();
other.originalFields = null;
other.zoneOffsets = null;
return other;
| protected void | computeFields()Converts the time value (millisecond offset from the Epoch) to calendar field values.
The time is not
recomputed first; to recompute the time, then the fields, call the
complete method.
int mask = 0;
if (isPartiallyNormalized()) {
// Determine which calendar fields need to be computed.
mask = getSetStateFields();
int fieldMask = ~mask & ALL_FIELDS;
if (fieldMask != 0 || cachedFixedDate == Long.MIN_VALUE) {
mask |= computeFields(fieldMask,
mask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK));
assert mask == ALL_FIELDS;
}
} else {
// Specify all fields
mask = ALL_FIELDS;
computeFields(mask, 0);
}
// After computing all the fields, set the field state to `COMPUTED'.
setFieldsComputed(mask);
| private int | computeFields(int fieldMask, int tzMask)This computeFields implements the conversion from UTC
(millisecond offset from the Epoch) to calendar
field values. fieldMask specifies which fields to change the
setting state to COMPUTED, although all fields are set to
the correct values. This is required to fix 4685354.
int zoneOffset = 0;
TimeZone tz = getZone();
if (zoneOffsets == null) {
zoneOffsets = new int[2];
}
if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
if (tz instanceof ZoneInfo) {
zoneOffset = ((ZoneInfo)tz).getOffsets(time, zoneOffsets);
} else {
zoneOffset = tz.getOffset(time);
zoneOffsets[0] = tz.getRawOffset();
zoneOffsets[1] = zoneOffset - zoneOffsets[0];
}
}
if (tzMask != 0) {
if (isFieldSet(tzMask, ZONE_OFFSET)) {
zoneOffsets[0] = internalGet(ZONE_OFFSET);
}
if (isFieldSet(tzMask, DST_OFFSET)) {
zoneOffsets[1] = internalGet(DST_OFFSET);
}
zoneOffset = zoneOffsets[0] + zoneOffsets[1];
}
// By computing time and zoneOffset separately, we can take
// the wider range of time+zoneOffset than the previous
// implementation.
long fixedDate = zoneOffset / ONE_DAY;
int timeOfDay = zoneOffset % (int)ONE_DAY;
fixedDate += time / ONE_DAY;
timeOfDay += (int) (time % ONE_DAY);
if (timeOfDay >= ONE_DAY) {
timeOfDay -= ONE_DAY;
++fixedDate;
} else {
while (timeOfDay < 0) {
timeOfDay += ONE_DAY;
--fixedDate;
}
}
fixedDate += EPOCH_OFFSET;
// See if we can use jdate to avoid date calculation.
if (fixedDate != cachedFixedDate || fixedDate < 0) {
jcal.getCalendarDateFromFixedDate(jdate, fixedDate);
cachedFixedDate = fixedDate;
}
int era = getEraIndex(jdate);
int year = jdate.getYear();
// Always set the ERA and YEAR values.
internalSet(ERA, era);
internalSet(YEAR, year);
int mask = fieldMask | (ERA_MASK|YEAR_MASK);
int month = jdate.getMonth() - 1; // 0-based
int dayOfMonth = jdate.getDayOfMonth();
// Set the basic date fields.
if ((fieldMask & (MONTH_MASK|DAY_OF_MONTH_MASK|DAY_OF_WEEK_MASK))
!= 0) {
internalSet(MONTH, month);
internalSet(DAY_OF_MONTH, dayOfMonth);
internalSet(DAY_OF_WEEK, jdate.getDayOfWeek());
mask |= MONTH_MASK|DAY_OF_MONTH_MASK|DAY_OF_WEEK_MASK;
}
if ((fieldMask & (HOUR_OF_DAY_MASK|AM_PM_MASK|HOUR_MASK
|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK)) != 0) {
if (timeOfDay != 0) {
int hours = timeOfDay / ONE_HOUR;
internalSet(HOUR_OF_DAY, hours);
internalSet(AM_PM, hours / 12); // Assume AM == 0
internalSet(HOUR, hours % 12);
int r = timeOfDay % ONE_HOUR;
internalSet(MINUTE, r / ONE_MINUTE);
r %= ONE_MINUTE;
internalSet(SECOND, r / ONE_SECOND);
internalSet(MILLISECOND, r % ONE_SECOND);
} else {
internalSet(HOUR_OF_DAY, 0);
internalSet(AM_PM, AM);
internalSet(HOUR, 0);
internalSet(MINUTE, 0);
internalSet(SECOND, 0);
internalSet(MILLISECOND, 0);
}
mask |= (HOUR_OF_DAY_MASK|AM_PM_MASK|HOUR_MASK
|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK);
}
if ((fieldMask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) != 0) {
internalSet(ZONE_OFFSET, zoneOffsets[0]);
internalSet(DST_OFFSET, zoneOffsets[1]);
mask |= (ZONE_OFFSET_MASK|DST_OFFSET_MASK);
}
if ((fieldMask & (DAY_OF_YEAR_MASK|WEEK_OF_YEAR_MASK
|WEEK_OF_MONTH_MASK|DAY_OF_WEEK_IN_MONTH_MASK)) != 0) {
int normalizedYear = jdate.getNormalizedYear();
// If it's a year of an era transition, we need to handle
// irregular year boundaries.
boolean transitionYear = isTransitionYear(jdate.getNormalizedYear());
int dayOfYear;
long fixedDateJan1;
if (transitionYear) {
fixedDateJan1 = getFixedDateJan1(jdate, fixedDate);
dayOfYear = (int)(fixedDate - fixedDateJan1) + 1;
} else if (normalizedYear == MIN_VALUES[YEAR]) {
CalendarDate dx = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
fixedDateJan1 = jcal.getFixedDate(dx);
dayOfYear = (int)(fixedDate - fixedDateJan1) + 1;
} else {
dayOfYear = (int) jcal.getDayOfYear(jdate);
fixedDateJan1 = fixedDate - dayOfYear + 1;
}
long fixedDateMonth1 = transitionYear ?
getFixedDateMonth1(jdate, fixedDate) : fixedDate - dayOfMonth + 1;
internalSet(DAY_OF_YEAR, dayOfYear);
internalSet(DAY_OF_WEEK_IN_MONTH, (dayOfMonth - 1) / 7 + 1);
int weekOfYear = getWeekNumber(fixedDateJan1, fixedDate);
// The spec is to calculate WEEK_OF_YEAR in the
// ISO8601-style. This creates problems, though.
if (weekOfYear == 0) {
// If the date belongs to the last week of the
// previous year, use the week number of "12/31" of
// the "previous" year. Again, if the previous year is
// a transition year, we need to take care of it.
// Usually the previous day of the first day of a year
// is December 31, which is not always true in the
// Japanese imperial calendar system.
long fixedDec31 = fixedDateJan1 - 1;
long prevJan1;
LocalGregorianCalendar.Date d = getCalendarDate(fixedDec31);
if (!(transitionYear || isTransitionYear(d.getNormalizedYear()))) {
prevJan1 = fixedDateJan1 - 365;
if (d.isLeapYear()) {
--prevJan1;
}
} else if (transitionYear) {
if (jdate.getYear() == 1) {
// As of Heisei (since Meiji) there's no case
// that there are multiple transitions in a
// year. Historically there was such
// case. There might be such case again in the
// future.
if (era > HEISEI) {
CalendarDate pd = eras[era - 1].getSinceDate();
if (normalizedYear == pd.getYear()) {
d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
}
} else {
d.setMonth(jcal.JANUARY).setDayOfMonth(1);
}
jcal.normalize(d);
prevJan1 = jcal.getFixedDate(d);
} else {
prevJan1 = fixedDateJan1 - 365;
if (d.isLeapYear()) {
--prevJan1;
}
}
} else {
CalendarDate cd = eras[getEraIndex(jdate)].getSinceDate();
d.setMonth(cd.getMonth()).setDayOfMonth(cd.getDayOfMonth());
jcal.normalize(d);
prevJan1 = jcal.getFixedDate(d);
}
weekOfYear = getWeekNumber(prevJan1, fixedDec31);
} else {
if (!transitionYear) {
// Regular years
if (weekOfYear >= 52) {
long nextJan1 = fixedDateJan1 + 365;
if (jdate.isLeapYear()) {
nextJan1++;
}
long nextJan1st = jcal.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
getFirstDayOfWeek());
int ndays = (int)(nextJan1st - nextJan1);
if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
// The first days forms a week in which the date is included.
weekOfYear = 1;
}
}
} else {
LocalGregorianCalendar.Date d = (LocalGregorianCalendar.Date) jdate.clone();
long nextJan1;
if (jdate.getYear() == 1) {
d.addYear(+1);
d.setMonth(jcal.JANUARY).setDayOfMonth(1);
nextJan1 = jcal.getFixedDate(d);
} else {
int nextEraIndex = getEraIndex(d) + 1;
CalendarDate cd = eras[nextEraIndex].getSinceDate();
d.setEra(eras[nextEraIndex]);
d.setDate(1, cd.getMonth(), cd.getDayOfMonth());
jcal.normalize(d);
nextJan1 = jcal.getFixedDate(d);
}
long nextJan1st = jcal.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
getFirstDayOfWeek());
int ndays = (int)(nextJan1st - nextJan1);
if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
// The first days forms a week in which the date is included.
weekOfYear = 1;
}
}
}
internalSet(WEEK_OF_YEAR, weekOfYear);
internalSet(WEEK_OF_MONTH, getWeekNumber(fixedDateMonth1, fixedDate));
mask |= (DAY_OF_YEAR_MASK|WEEK_OF_YEAR_MASK|WEEK_OF_MONTH_MASK|DAY_OF_WEEK_IN_MONTH_MASK);
}
return mask;
| protected void | computeTime()Converts calendar field values to the time value (millisecond
offset from the Epoch).
// In non-lenient mode, perform brief checking of calendar
// fields which have been set externally. Through this
// checking, the field values are stored in originalFields[]
// to see if any of them are normalized later.
if (!isLenient()) {
if (originalFields == null) {
originalFields = new int[FIELD_COUNT];
}
for (int field = 0; field < FIELD_COUNT; field++) {
int value = internalGet(field);
if (isExternallySet(field)) {
// Quick validation for any out of range values
if (value < getMinimum(field) || value > getMaximum(field)) {
throw new IllegalArgumentException(getFieldName(field));
}
}
originalFields[field] = value;
}
}
// Let the super class determine which calendar fields to be
// used to calculate the time.
int fieldMask = selectFields();
int year;
int era;
if (isSet(ERA)) {
era = internalGet(ERA);
year = isSet(YEAR) ? internalGet(YEAR) : 1;
} else {
if (isSet(YEAR)) {
era = eras.length - 1;
year = internalGet(YEAR);
} else {
// Equivalent to 1970 (Gregorian)
era = SHOWA;
year = 45;
}
}
// Calculate the time of day. We rely on the convention that
// an UNSET field has 0.
long timeOfDay = 0;
if (isFieldSet(fieldMask, HOUR_OF_DAY)) {
timeOfDay += (long) internalGet(HOUR_OF_DAY);
} else {
timeOfDay += internalGet(HOUR);
// The default value of AM_PM is 0 which designates AM.
if (isFieldSet(fieldMask, AM_PM)) {
timeOfDay += 12 * internalGet(AM_PM);
}
}
timeOfDay *= 60;
timeOfDay += internalGet(MINUTE);
timeOfDay *= 60;
timeOfDay += internalGet(SECOND);
timeOfDay *= 1000;
timeOfDay += internalGet(MILLISECOND);
// Convert the time of day to the number of days and the
// millisecond offset from midnight.
long fixedDate = timeOfDay / ONE_DAY;
timeOfDay %= ONE_DAY;
while (timeOfDay < 0) {
timeOfDay += ONE_DAY;
--fixedDate;
}
// Calculate the fixed date since January 1, 1 (Gregorian).
fixedDate += getFixedDate(era, year, fieldMask);
// millis represents local wall-clock time in milliseconds.
long millis = (fixedDate - EPOCH_OFFSET) * ONE_DAY + timeOfDay;
// Compute the time zone offset and DST offset. There are two potential
// ambiguities here. We'll assume a 2:00 am (wall time) switchover time
// for discussion purposes here.
// 1. The transition into DST. Here, a designated time of 2:00 am - 2:59 am
// can be in standard or in DST depending. However, 2:00 am is an invalid
// representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
// We assume standard time.
// 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am
// can be in standard or DST. Both are valid representations (the rep
// jumps from 1:59:59 DST to 1:00:00 Std).
// Again, we assume standard time.
// We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
// or DST_OFFSET fields; then we use those fields.
TimeZone zone = getZone();
if (zoneOffsets == null) {
zoneOffsets = new int[2];
}
int tzMask = fieldMask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK);
if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
if (zone instanceof ZoneInfo) {
((ZoneInfo)zone).getOffsetsByWall(millis, zoneOffsets);
} else {
zone.getOffsets(millis - zone.getRawOffset(), zoneOffsets);
}
}
if (tzMask != 0) {
if (isFieldSet(tzMask, ZONE_OFFSET)) {
zoneOffsets[0] = internalGet(ZONE_OFFSET);
}
if (isFieldSet(tzMask, DST_OFFSET)) {
zoneOffsets[1] = internalGet(DST_OFFSET);
}
}
// Adjust the time zone offset values to get the UTC time.
millis -= zoneOffsets[0] + zoneOffsets[1];
// Set this calendar's time in milliseconds
time = millis;
int mask = computeFields(fieldMask | getSetStateFields(), tzMask);
if (!isLenient()) {
for (int field = 0; field < FIELD_COUNT; field++) {
if (!isExternallySet(field)) {
continue;
}
if (originalFields[field] != internalGet(field)) {
int wrongValue = internalGet(field);
// Restore the original field values
System.arraycopy(originalFields, 0, fields, 0, fields.length);
throw new IllegalArgumentException(getFieldName(field) + "=" + wrongValue
+ ", expected " + originalFields[field]);
}
}
}
setFieldsNormalized(mask);
| public boolean | equals(java.lang.Object obj)Compares this JapaneseImperialCalendar to the specified
Object . The result is true if and
only if the argument is a JapaneseImperialCalendar object
that represents the same time value (millisecond offset from
the Epoch) under the same
Calendar parameters.
return obj instanceof JapaneseImperialCalendar &&
super.equals(obj);
| public int | getActualMaximum(int field)Returns the maximum value that this calendar field could have,
taking into consideration the given time value and the current
values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and
{@link Calendar#getTimeZone() getTimeZone} methods.
For example, if the date of this instance is Heisei 16February 1,
the actual maximum value of the DAY_OF_MONTH field
is 29 because Heisei 16 is a leap year, and if the date of this
instance is Heisei 17 February 1, it's 28.
final int fieldsForFixedMax = ERA_MASK|DAY_OF_WEEK_MASK|HOUR_MASK|AM_PM_MASK|
HOUR_OF_DAY_MASK|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK|
ZONE_OFFSET_MASK|DST_OFFSET_MASK;
if ((fieldsForFixedMax & (1<<field)) != 0) {
return getMaximum(field);
}
JapaneseImperialCalendar jc = getNormalizedCalendar();
LocalGregorianCalendar.Date date = jc.jdate;
int normalizedYear = date.getNormalizedYear();
int value = -1;
switch (field) {
case MONTH:
{
value = DECEMBER;
if (isTransitionYear(date.getNormalizedYear())) {
// TODO: there may be multiple transitions in a year.
int eraIndex = getEraIndex(date);
if (date.getYear() != 1) {
eraIndex++;
assert eraIndex < eras.length;
}
long transition = sinceFixedDates[eraIndex];
long fd = jc.cachedFixedDate;
if (fd < transition) {
LocalGregorianCalendar.Date ldate
= (LocalGregorianCalendar.Date) date.clone();
jcal.getCalendarDateFromFixedDate(ldate, transition - 1);
value = ldate.getMonth() - 1;
}
} else {
LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MAX_VALUE,
getZone());
if (date.getEra() == d.getEra() && date.getYear() == d.getYear()) {
value = d.getMonth() - 1;
}
}
}
break;
case DAY_OF_MONTH:
value = jcal.getMonthLength(date);
break;
case DAY_OF_YEAR:
{
if (isTransitionYear(date.getNormalizedYear())) {
// Handle transition year.
// TODO: there may be multiple transitions in a year.
int eraIndex = getEraIndex(date);
if (date.getYear() != 1) {
eraIndex++;
assert eraIndex < eras.length;
}
long transition = sinceFixedDates[eraIndex];
long fd = jc.cachedFixedDate;
CalendarDate d = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
d.setDate(date.getNormalizedYear(), BaseCalendar.JANUARY, 1);
if (fd < transition) {
value = (int)(transition - gcal.getFixedDate(d));
} else {
d.addYear(+1);
value = (int)(gcal.getFixedDate(d) - transition);
}
} else {
LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MAX_VALUE,
getZone());
if (date.getEra() == d.getEra() && date.getYear() == d.getYear()) {
long fd = jcal.getFixedDate(d);
long jan1 = getFixedDateJan1(d, fd);
value = (int)(fd - jan1) + 1;
} else if (date.getYear() == getMinimum(YEAR)) {
CalendarDate d1 = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
long fd1 = jcal.getFixedDate(d1);
d1.addYear(1);
d1.setMonth(BaseCalendar.JANUARY).setDayOfMonth(1);
jcal.normalize(d1);
long fd2 = jcal.getFixedDate(d1);
value = (int)(fd2 - fd1);
} else {
value = jcal.getYearLength(date);
}
}
}
break;
case WEEK_OF_YEAR:
{
if (!isTransitionYear(date.getNormalizedYear())) {
LocalGregorianCalendar.Date jd = jcal.getCalendarDate(Long.MAX_VALUE,
getZone());
if (date.getEra() == jd.getEra() && date.getYear() == jd.getYear()) {
long fd = jcal.getFixedDate(jd);
long jan1 = getFixedDateJan1(jd, fd);
value = getWeekNumber(jan1, fd);
} else if (date.getEra() == null && date.getYear() == getMinimum(YEAR)) {
CalendarDate d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
// shift 400 years to avoid underflow
d.addYear(+400);
jcal.normalize(d);
jd.setEra(d.getEra());
jd.setDate(d.getYear() + 1, BaseCalendar.JANUARY, 1);
jcal.normalize(jd);
long jan1 = jcal.getFixedDate(d);
long nextJan1 = jcal.getFixedDate(jd);
long nextJan1st = jcal.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
getFirstDayOfWeek());
int ndays = (int)(nextJan1st - nextJan1);
if (ndays >= getMinimalDaysInFirstWeek()) {
nextJan1st -= 7;
}
value = getWeekNumber(jan1, nextJan1st);
} else {
// Get the day of week of January 1 of the year
CalendarDate d = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
d.setDate(date.getNormalizedYear(), BaseCalendar.JANUARY, 1);
int dayOfWeek = gcal.getDayOfWeek(d);
// Normalize the day of week with the firstDayOfWeek value
dayOfWeek -= getFirstDayOfWeek();
if (dayOfWeek < 0) {
dayOfWeek += 7;
}
value = 52;
int magic = dayOfWeek + getMinimalDaysInFirstWeek() - 1;
if ((magic == 6) ||
(date.isLeapYear() && (magic == 5 || magic == 12))) {
value++;
}
}
break;
}
if (jc == this) {
jc = (JapaneseImperialCalendar) jc.clone();
}
int max = getActualMaximum(DAY_OF_YEAR);
jc.set(DAY_OF_YEAR, max);
value = jc.get(WEEK_OF_YEAR);
if (value == 1 && max > 7) {
jc.add(WEEK_OF_YEAR, -1);
value = jc.get(WEEK_OF_YEAR);
}
}
break;
case WEEK_OF_MONTH:
{
LocalGregorianCalendar.Date jd = jcal.getCalendarDate(Long.MAX_VALUE,
getZone());
if (!(date.getEra() == jd.getEra() && date.getYear() == jd.getYear())) {
CalendarDate d = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
d.setDate(date.getNormalizedYear(), date.getMonth(), 1);
int dayOfWeek = gcal.getDayOfWeek(d);
int monthLength = gcal.getMonthLength(d);
dayOfWeek -= getFirstDayOfWeek();
if (dayOfWeek < 0) {
dayOfWeek += 7;
}
int nDaysFirstWeek = 7 - dayOfWeek; // # of days in the first week
value = 3;
if (nDaysFirstWeek >= getMinimalDaysInFirstWeek()) {
value++;
}
monthLength -= nDaysFirstWeek + 7 * 3;
if (monthLength > 0) {
value++;
if (monthLength > 7) {
value++;
}
}
} else {
long fd = jcal.getFixedDate(jd);
long month1 = fd - jd.getDayOfMonth() + 1;
value = getWeekNumber(month1, fd);
}
}
break;
case DAY_OF_WEEK_IN_MONTH:
{
int ndays, dow1;
int dow = date.getDayOfWeek();
BaseCalendar.Date d = (BaseCalendar.Date) date.clone();
ndays = jcal.getMonthLength(d);
d.setDayOfMonth(1);
jcal.normalize(d);
dow1 = d.getDayOfWeek();
int x = dow - dow1;
if (x < 0) {
x += 7;
}
ndays -= x;
value = (ndays + 6) / 7;
}
break;
case YEAR:
{
CalendarDate jd = jcal.getCalendarDate(jc.getTimeInMillis(), getZone());
CalendarDate d;
int eraIndex = getEraIndex(date);
if (eraIndex == eras.length - 1) {
d = jcal.getCalendarDate(Long.MAX_VALUE, getZone());
value = d.getYear();
// Use an equivalent year for the
// getYearOffsetInMillis call to avoid overflow.
if (value > 400) {
jd.setYear(value - 400);
}
} else {
d = jcal.getCalendarDate(eras[eraIndex + 1].getSince(getZone()) - 1,
getZone());
value = d.getYear();
// Use the same year as d.getYear() to be
// consistent with leap and common years.
jd.setYear(value);
}
jcal.normalize(jd);
if (getYearOffsetInMillis(jd) > getYearOffsetInMillis(d)) {
value--;
}
}
break;
default:
throw new ArrayIndexOutOfBoundsException(field);
}
return value;
| public int | getActualMinimum(int field)Returns the minimum value that this calendar field could have,
taking into consideration the given time value and the current
values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and {@link Calendar#getTimeZone() getTimeZone} methods.
if (!isFieldSet(YEAR_MASK|MONTH_MASK|WEEK_OF_YEAR_MASK, field)) {
return getMinimum(field);
}
int value = 0;
JapaneseImperialCalendar jc = getNormalizedCalendar();
// Get a local date which includes time of day and time zone,
// which are missing in jc.jdate.
LocalGregorianCalendar.Date jd = jcal.getCalendarDate(jc.getTimeInMillis(),
getZone());
int eraIndex = getEraIndex(jd);
switch (field) {
case YEAR:
{
if (eraIndex > BEFORE_MEIJI) {
value = 1;
long since = eras[eraIndex].getSince(getZone());
CalendarDate d = jcal.getCalendarDate(since, getZone());
// Use the same year in jd to take care of leap
// years. i.e., both jd and d must agree on leap
// or common years.
jd.setYear(d.getYear());
jcal.normalize(jd);
assert jd.isLeapYear() == d.isLeapYear();
if (getYearOffsetInMillis(jd) < getYearOffsetInMillis(d)) {
value++;
}
} else {
value = getMinimum(field);
CalendarDate d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
// Use an equvalent year of d.getYear() if
// possible. Otherwise, ignore the leap year and
// common year difference.
int y = d.getYear();
if (y > 400) {
y -= 400;
}
jd.setYear(y);
jcal.normalize(jd);
if (getYearOffsetInMillis(jd) < getYearOffsetInMillis(d)) {
value++;
}
}
}
break;
case MONTH:
{
// In Before Meiji and Meiji, January is the first month.
if (eraIndex > MEIJI && jd.getYear() == 1) {
long since = eras[eraIndex].getSince(getZone());
CalendarDate d = jcal.getCalendarDate(since, getZone());
value = d.getMonth() - 1;
if (jd.getDayOfMonth() < d.getDayOfMonth()) {
value++;
}
}
}
break;
case WEEK_OF_YEAR:
{
value = 1;
CalendarDate d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
// shift 400 years to avoid underflow
d.addYear(+400);
jcal.normalize(d);
jd.setEra(d.getEra());
jd.setYear(d.getYear());
jcal.normalize(jd);
long jan1 = jcal.getFixedDate(d);
long fd = jcal.getFixedDate(jd);
int woy = getWeekNumber(jan1, fd);
long day1 = fd - (7 * (woy - 1));
if ((day1 < jan1) ||
(day1 == jan1 &&
jd.getTimeOfDay() < d.getTimeOfDay())) {
value++;
}
}
break;
}
return value;
| private static final sun.util.calendar.LocalGregorianCalendar$Date | getCalendarDate(long fd)Returns a LocalGregorianCalendar.Date produced from the specified fixed date.
LocalGregorianCalendar.Date d = jcal.newCalendarDate(TimeZone.NO_TIMEZONE);
jcal.getCalendarDateFromFixedDate(d, fd);
return d;
| public java.lang.String | getDisplayName(int field, int style, java.util.Locale locale)
if (!checkDisplayNameParams(field, style, SHORT, LONG, locale,
ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
return null;
}
// "GanNen" is supported only in the LONG style.
if (field == YEAR
&& (style == SHORT || get(YEAR) != 1 || get(ERA) == 0)) {
return null;
}
ResourceBundle rb = LocaleData.getDateFormatData(locale);
String name = null;
String key = getKey(field, style);
if (key != null) {
String[] strings = rb.getStringArray(key);
if (field == YEAR) {
if (strings.length > 0) {
name = strings[0];
}
} else {
int index = get(field);
// If the ERA value is out of range for strings, then
// try to get its name or abbreviation from the Era instance.
if (field == ERA && index >= strings.length && index < eras.length) {
Era era = eras[index];
name = (style == SHORT) ? era.getAbbreviation() : era.getName();
} else {
if (field == DAY_OF_WEEK)
--index;
name = strings[index];
}
}
}
return name;
| public java.util.Map | getDisplayNames(int field, int style, java.util.Locale locale)
if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
return null;
}
if (style == ALL_STYLES) {
Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale);
if (field == AM_PM) {
return shortNames;
}
Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale);
if (shortNames == null) {
return longNames;
}
if (longNames != null) {
shortNames.putAll(longNames);
}
return shortNames;
}
// SHORT or LONG
return getDisplayNamesImpl(field, style, locale);
| private java.util.Map | getDisplayNamesImpl(int field, int style, java.util.Locale locale)
ResourceBundle rb = LocaleData.getDateFormatData(locale);
String key = getKey(field, style);
Map<String,Integer> map = new HashMap<String,Integer>();
if (key != null) {
String[] strings = rb.getStringArray(key);
if (field == YEAR) {
if (strings.length > 0) {
map.put(strings[0], 1);
}
} else {
int base = (field == DAY_OF_WEEK) ? 1 : 0;
for (int i = 0; i < strings.length; i++) {
map.put(strings[i], base + i);
}
// If strings[] has fewer than eras[], get more names from eras[].
if (field == ERA && strings.length < eras.length) {
for (int i = strings.length; i < eras.length; i++) {
Era era = eras[i];
String name = (style == SHORT) ? era.getAbbreviation() : era.getName();
map.put(name, i);
}
}
}
}
return map.size() > 0 ? map : null;
| private static final int | getEraIndex(sun.util.calendar.LocalGregorianCalendar$Date date)
Era era = date.getEra();
for (int i = eras.length - 1; i > 0; i--) {
if (eras[i] == era) {
return i;
}
}
return 0;
| private long | getFixedDate(int era, int year, int fieldMask)Computes the fixed date under either the Gregorian or the
Julian calendar, using the given year and the specified calendar fields.
int month = JANUARY;
int firstDayOfMonth = 1;
if (isFieldSet(fieldMask, MONTH)) {
// No need to check if MONTH has been set (no isSet(MONTH)
// call) since its unset value happens to be JANUARY (0).
month = internalGet(MONTH);
// If the month is out of range, adjust it into range.
if (month > DECEMBER) {
year += month / 12;
month %= 12;
} else if (month < JANUARY) {
int[] rem = new int[1];
year += CalendarUtils.floorDivide(month, 12, rem);
month = rem[0];
}
} else {
if (year == 1 && era != 0) {
CalendarDate d = eras[era].getSinceDate();
month = d.getMonth() - 1;
firstDayOfMonth = d.getDayOfMonth();
}
}
// Adjust the base date if year is the minimum value.
if (year == MIN_VALUES[YEAR]) {
CalendarDate dx = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
int m = dx.getMonth() - 1;
if (month < m)
month = m;
if (month == m)
firstDayOfMonth = dx.getDayOfMonth();
}
LocalGregorianCalendar.Date date = jcal.newCalendarDate(TimeZone.NO_TIMEZONE);
date.setEra(era > 0 ? eras[era] : null);
date.setDate(year, month + 1, firstDayOfMonth);
jcal.normalize(date);
// Get the fixed date since Jan 1, 1 (Gregorian). We are on
// the first day of either `month' or January in 'year'.
long fixedDate = jcal.getFixedDate(date);
if (isFieldSet(fieldMask, MONTH)) {
// Month-based calculations
if (isFieldSet(fieldMask, DAY_OF_MONTH)) {
// We are on the "first day" of the month (which may
// not be 1). Just add the offset if DAY_OF_MONTH is
// set. If the isSet call returns false, that means
// DAY_OF_MONTH has been selected just because of the
// selected combination. We don't need to add any
// since the default value is the "first day".
if (isSet(DAY_OF_MONTH)) {
// To avoid underflow with DAY_OF_MONTH-firstDayOfMonth, add
// DAY_OF_MONTH, then subtract firstDayOfMonth.
fixedDate += internalGet(DAY_OF_MONTH);
fixedDate -= firstDayOfMonth;
}
} else {
if (isFieldSet(fieldMask, WEEK_OF_MONTH)) {
long firstDayOfWeek = jcal.getDayOfWeekDateOnOrBefore(fixedDate + 6,
getFirstDayOfWeek());
// If we have enough days in the first week, then
// move to the previous week.
if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
firstDayOfWeek -= 7;
}
if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
firstDayOfWeek = jcal.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
internalGet(DAY_OF_WEEK));
}
// In lenient mode, we treat days of the previous
// months as a part of the specified
// WEEK_OF_MONTH. See 4633646.
fixedDate = firstDayOfWeek + 7 * (internalGet(WEEK_OF_MONTH) - 1);
} else {
int dayOfWeek;
if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
dayOfWeek = internalGet(DAY_OF_WEEK);
} else {
dayOfWeek = getFirstDayOfWeek();
}
// We are basing this on the day-of-week-in-month. The only
// trickiness occurs if the day-of-week-in-month is
// negative.
int dowim;
if (isFieldSet(fieldMask, DAY_OF_WEEK_IN_MONTH)) {
dowim = internalGet(DAY_OF_WEEK_IN_MONTH);
} else {
dowim = 1;
}
if (dowim >= 0) {
fixedDate = jcal.getDayOfWeekDateOnOrBefore(fixedDate + (7 * dowim) - 1,
dayOfWeek);
} else {
// Go to the first day of the next week of
// the specified week boundary.
int lastDate = monthLength(month, year) + (7 * (dowim + 1));
// Then, get the day of week date on or before the last date.
fixedDate = jcal.getDayOfWeekDateOnOrBefore(fixedDate + lastDate - 1,
dayOfWeek);
}
}
}
} else {
// We are on the first day of the year.
if (isFieldSet(fieldMask, DAY_OF_YEAR)) {
if (isTransitionYear(date.getNormalizedYear())) {
fixedDate = getFixedDateJan1(date, fixedDate);
}
// Add the offset, then subtract 1. (Make sure to avoid underflow.)
fixedDate += internalGet(DAY_OF_YEAR);
fixedDate--;
} else {
long firstDayOfWeek = jcal.getDayOfWeekDateOnOrBefore(fixedDate + 6,
getFirstDayOfWeek());
// If we have enough days in the first week, then move
// to the previous week.
if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
firstDayOfWeek -= 7;
}
if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
int dayOfWeek = internalGet(DAY_OF_WEEK);
if (dayOfWeek != getFirstDayOfWeek()) {
firstDayOfWeek = jcal.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
dayOfWeek);
}
}
fixedDate = firstDayOfWeek + 7 * ((long)internalGet(WEEK_OF_YEAR) - 1);
}
}
return fixedDate;
| private final long | getFixedDateJan1(sun.util.calendar.LocalGregorianCalendar$Date date, long fixedDate)Returns the fixed date of the first day of the year (usually
January 1) before the specified date.
Era era = date.getEra();
if (date.getEra() != null && date.getYear() == 1) {
for (int eraIndex = getEraIndex(date); eraIndex > 0; eraIndex--) {
CalendarDate d = eras[eraIndex].getSinceDate();
long fd = gcal.getFixedDate(d);
// There might be multiple era transitions in a year.
if (fd > fixedDate) {
continue;
}
return fd;
}
}
CalendarDate d = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
d.setDate(date.getNormalizedYear(), gcal.JANUARY, 1);
return gcal.getFixedDate(d);
| private final long | getFixedDateMonth1(sun.util.calendar.LocalGregorianCalendar$Date date, long fixedDate)Returns the fixed date of the first date of the month (usually
the 1st of the month) before the specified date.
int eraIndex = getTransitionEraIndex(date);
if (eraIndex != -1) {
long transition = sinceFixedDates[eraIndex];
// If the given date is on or after the transition date, then
// return the transition date.
if (transition <= fixedDate) {
return transition;
}
}
// Otherwise, we can use the 1st day of the month.
return fixedDate - date.getDayOfMonth() + 1;
| public int | getGreatestMinimum(int field)Returns the highest minimum value for the given calendar field
of this GregorianCalendar instance. The highest
minimum value is defined as the largest value returned by
{@link #getActualMinimum(int)} for any possible time value,
taking into consideration the current values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and {@link Calendar#getTimeZone() getTimeZone} methods.
return field == YEAR ? 1 : MIN_VALUES[field];
| private java.lang.String | getKey(int field, int style)
String className = JapaneseImperialCalendar.class.getName();
StringBuilder key = new StringBuilder();
switch (field) {
case ERA:
key.append(className);
if (style == SHORT) {
key.append(".short");
}
key.append(".Eras");
break;
case YEAR:
key.append(className).append(".FirstYear");
break;
case MONTH:
key.append(style == SHORT ? "MonthAbbreviations" : "MonthNames");
break;
case DAY_OF_WEEK:
key.append(style == SHORT ? "DayAbbreviations" : "DayNames");
break;
case AM_PM:
key.append("AmPmMarkers");
break;
}
return key.length() > 0 ? key.toString() : null;
| public int | getLeastMaximum(int field)Returns the lowest maximum value for the given calendar field
of this GregorianCalendar instance. The lowest
maximum value is defined as the smallest value returned by
{@link #getActualMaximum(int)} for any possible time value,
taking into consideration the current values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and {@link Calendar#getTimeZone() getTimeZone} methods.
switch (field) {
case YEAR:
{
return Math.min(LEAST_MAX_VALUES[YEAR], getMaximum(YEAR));
}
}
return LEAST_MAX_VALUES[field];
| public int | getMaximum(int field)Returns the maximum value for the given calendar field of this
GregorianCalendar instance. The maximum value is
defined as the largest value returned by the {@link
Calendar#get(int) get} method for any possible time value,
taking into consideration the current values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and {@link Calendar#getTimeZone() getTimeZone} methods.
switch (field) {
case YEAR:
{
// The value should depend on the time zone of this calendar.
LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MAX_VALUE,
getZone());
return Math.max(LEAST_MAX_VALUES[YEAR], d.getYear());
}
}
return MAX_VALUES[field];
| public int | getMinimum(int field)Returns the minimum value for the given calendar field of this
Calendar instance. The minimum value is
defined as the smallest value returned by the {@link
Calendar#get(int) get} method for any possible time value,
taking into consideration the current values of the
{@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
{@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
and {@link Calendar#getTimeZone() getTimeZone} methods.
return MIN_VALUES[field];
| private final java.util.JapaneseImperialCalendar | getNormalizedCalendar()Returns this object if it's normalized (all fields and time are
in sync). Otherwise, a cloned object is returned after calling
complete() in lenient mode.
JapaneseImperialCalendar jc;
if (isFullyNormalized()) {
jc = this;
} else {
// Create a clone and normalize the calendar fields
jc = (JapaneseImperialCalendar) this.clone();
jc.setLenient(true);
jc.complete();
}
return jc;
| private static final int | getRolledValue(int value, int amount, int min, int max)Returns the new value after 'roll'ing the specified value and amount.
assert value >= min && value <= max;
int range = max - min + 1;
amount %= range;
int n = value + amount;
if (n > max) {
n -= range;
} else if (n < min) {
n += range;
}
assert n >= min && n <= max;
return n;
| public java.util.TimeZone | getTimeZone()
TimeZone zone = super.getTimeZone();
// To share the zone by the CalendarDate
jdate.setZone(zone);
return zone;
| private static final int | getTransitionEraIndex(sun.util.calendar.LocalGregorianCalendar$Date date)Returns the index to the new era if the given date is in a
transition month. For example, if the give date is Heisei 1
(1989) January 20, then the era index for Heisei is
returned. Likewise, if the given date is Showa 64 (1989)
January 3, then the era index for Heisei is returned. If the
given date is not in any transition month, then -1 is returned.
int eraIndex = getEraIndex(date);
CalendarDate transitionDate = eras[eraIndex].getSinceDate();
if (transitionDate.getYear() == date.getNormalizedYear() &&
transitionDate.getMonth() == date.getMonth()) {
return eraIndex;
}
if (eraIndex < eras.length - 1) {
transitionDate = eras[++eraIndex].getSinceDate();
if (transitionDate.getYear() == date.getNormalizedYear() &&
transitionDate.getMonth() == date.getMonth()) {
return eraIndex;
}
}
return -1;
| private final int | getWeekNumber(long fixedDay1, long fixedDate)Returns the number of weeks in a period between fixedDay1 and
fixedDate. The getFirstDayOfWeek-getMinimalDaysInFirstWeek rule
is applied to calculate the number of weeks.
// We can always use `jcal' since Julian and Gregorian are the
// same thing for this calculation.
long fixedDay1st = jcal.getDayOfWeekDateOnOrBefore(fixedDay1 + 6,
getFirstDayOfWeek());
int ndays = (int)(fixedDay1st - fixedDay1);
assert ndays <= 7;
if (ndays >= getMinimalDaysInFirstWeek()) {
fixedDay1st -= 7;
}
int normalizedDayOfPeriod = (int)(fixedDate - fixedDay1st);
if (normalizedDayOfPeriod >= 0) {
return normalizedDayOfPeriod / 7 + 1;
}
return CalendarUtils.floorDivide(normalizedDayOfPeriod, 7) + 1;
| private final long | getYearOffsetInMillis(sun.util.calendar.CalendarDate date)Returns the millisecond offset from the beginning of the
year. In the year for Long.MIN_VALUE, it's a pseudo value
beyond the limit. The given CalendarDate object must have been
normalized before calling this method.
long t = (jcal.getDayOfYear(date) - 1) * ONE_DAY;
return t + date.getTimeOfDay() - date.getZoneOffset();
| public int | hashCode()Generates the hash code for this
JapaneseImperialCalendar object.
return super.hashCode() ^ jdate.hashCode();
| private final int | internalGetEra()Returns the ERA. We need a special method for this because the
default ERA is the current era, but a zero (unset) ERA means before Meiji.
return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
| private final boolean | isTransitionYear(int normalizedYear)
for (int i = eras.length - 1; i > 0; i--) {
int transitionYear = eras[i].getSinceDate().getYear();
if (normalizedYear == transitionYear) {
return true;
}
if (normalizedYear > transitionYear) {
break;
}
}
return false;
| private final int | monthLength(int month, int gregorianYear)Returns the length of the specified month in the specified
Gregorian year. The year number must be normalized.
return CalendarUtils.isGregorianLeapYear(gregorianYear) ?
GregorianCalendar.LEAP_MONTH_LENGTH[month] : GregorianCalendar.MONTH_LENGTH[month];
| private final int | monthLength(int month)Returns the length of the specified month in the year provided
by internalGet(YEAR).
assert jdate.isNormalized();
return jdate.isLeapYear() ?
GregorianCalendar.LEAP_MONTH_LENGTH[month] : GregorianCalendar.MONTH_LENGTH[month];
| private final void | pinDayOfMonth(sun.util.calendar.LocalGregorianCalendar$Date date)After adjustments such as add(MONTH), add(YEAR), we don't want the
month to jump around. E.g., we don't want Jan 31 + 1 month to go to Mar
3, we want it to go to Feb 28. Adjustments which might run into this
problem call this method to retain the proper month.
int year = date.getYear();
int dom = date.getDayOfMonth();
if (year != getMinimum(YEAR)) {
date.setDayOfMonth(1);
jcal.normalize(date);
int monthLength = jcal.getMonthLength(date);
if (dom > monthLength) {
date.setDayOfMonth(monthLength);
} else {
date.setDayOfMonth(dom);
}
jcal.normalize(date);
} else {
LocalGregorianCalendar.Date d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
LocalGregorianCalendar.Date realDate = jcal.getCalendarDate(time, getZone());
long tod = realDate.getTimeOfDay();
// Use an equivalent year.
realDate.addYear(+400);
realDate.setMonth(date.getMonth());
realDate.setDayOfMonth(1);
jcal.normalize(realDate);
int monthLength = jcal.getMonthLength(realDate);
if (dom > monthLength) {
realDate.setDayOfMonth(monthLength);
} else {
if (dom < d.getDayOfMonth()) {
realDate.setDayOfMonth(d.getDayOfMonth());
} else {
realDate.setDayOfMonth(dom);
}
}
if (realDate.getDayOfMonth() == d.getDayOfMonth() && tod < d.getTimeOfDay()) {
realDate.setDayOfMonth(Math.min(dom + 1, monthLength));
}
// restore the year.
date.setDate(year, realDate.getMonth(), realDate.getDayOfMonth());
// Don't normalize date here so as not to cause underflow.
}
| private void | readObject(java.io.ObjectInputStream stream)Updates internal state.
stream.defaultReadObject();
if (jdate == null) {
jdate = jcal.newCalendarDate(getZone());
cachedFixedDate = Long.MIN_VALUE;
}
| public void | roll(int field, boolean up)
roll(field, up ? +1 : -1);
| public void | roll(int field, int amount)Adds a signed amount to the specified calendar field without changing larger fields.
A negative roll amount means to subtract from field without changing
larger fields. If the specified amount is 0, this method performs nothing.
This method calls {@link #complete()} before adding the
amount so that all the calendar fields are normalized. If there
is any calendar field having an out-of-range value in non-lenient mode, then an
IllegalArgumentException is thrown.
// If amount == 0, do nothing even the given field is out of
// range. This is tested by JCK.
if (amount == 0) {
return;
}
if (field < 0 || field >= ZONE_OFFSET) {
throw new IllegalArgumentException();
}
// Sync the time and calendar fields.
complete();
int min = getMinimum(field);
int max = getMaximum(field);
switch (field) {
case ERA:
case AM_PM:
case MINUTE:
case SECOND:
case MILLISECOND:
// These fields are handled simply, since they have fixed
// minima and maxima. Other fields are complicated, since
// the range within they must roll varies depending on the
// date, a time zone and the era transitions.
break;
case HOUR:
case HOUR_OF_DAY:
{
int unit = max + 1; // 12 or 24 hours
int h = internalGet(field);
int nh = (h + amount) % unit;
if (nh < 0) {
nh += unit;
}
time += ONE_HOUR * (nh - h);
// The day might have changed, which could happen if
// the daylight saving time transition brings it to
// the next day, although it's very unlikely. But we
// have to make sure not to change the larger fields.
CalendarDate d = jcal.getCalendarDate(time, getZone());
if (internalGet(DAY_OF_MONTH) != d.getDayOfMonth()) {
d.setEra(jdate.getEra());
d.setDate(internalGet(YEAR),
internalGet(MONTH) + 1,
internalGet(DAY_OF_MONTH));
if (field == HOUR) {
assert (internalGet(AM_PM) == PM);
d.addHours(+12); // restore PM
}
time = jcal.getTime(d);
}
int hourOfDay = d.getHours();
internalSet(field, hourOfDay % unit);
if (field == HOUR) {
internalSet(HOUR_OF_DAY, hourOfDay);
} else {
internalSet(AM_PM, hourOfDay / 12);
internalSet(HOUR, hourOfDay % 12);
}
// Time zone offset and/or daylight saving might have changed.
int zoneOffset = d.getZoneOffset();
int saving = d.getDaylightSaving();
internalSet(ZONE_OFFSET, zoneOffset - saving);
internalSet(DST_OFFSET, saving);
return;
}
case YEAR:
min = getActualMinimum(field);
max = getActualMaximum(field);
break;
case MONTH:
// Rolling the month involves both pinning the final value to [0, 11]
// and adjusting the DAY_OF_MONTH if necessary. We only adjust the
// DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
// E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
{
if (!isTransitionYear(jdate.getNormalizedYear())) {
int year = jdate.getYear();
if (year == getMaximum(YEAR)) {
CalendarDate jd = jcal.getCalendarDate(time, getZone());
CalendarDate d = jcal.getCalendarDate(Long.MAX_VALUE, getZone());
max = d.getMonth() - 1;
int n = getRolledValue(internalGet(field), amount, min, max);
if (n == max) {
// To avoid overflow, use an equivalent year.
jd.addYear(-400);
jd.setMonth(n + 1);
if (jd.getDayOfMonth() > d.getDayOfMonth()) {
jd.setDayOfMonth(d.getDayOfMonth());
jcal.normalize(jd);
}
if (jd.getDayOfMonth() == d.getDayOfMonth()
&& jd.getTimeOfDay() > d.getTimeOfDay()) {
jd.setMonth(n + 1);
jd.setDayOfMonth(d.getDayOfMonth() - 1);
jcal.normalize(jd);
// Month may have changed by the normalization.
n = jd.getMonth() - 1;
}
set(DAY_OF_MONTH, jd.getDayOfMonth());
}
set(MONTH, n);
} else if (year == getMinimum(YEAR)) {
CalendarDate jd = jcal.getCalendarDate(time, getZone());
CalendarDate d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
min = d.getMonth() - 1;
int n = getRolledValue(internalGet(field), amount, min, max);
if (n == min) {
// To avoid underflow, use an equivalent year.
jd.addYear(+400);
jd.setMonth(n + 1);
if (jd.getDayOfMonth() < d.getDayOfMonth()) {
jd.setDayOfMonth(d.getDayOfMonth());
jcal.normalize(jd);
}
if (jd.getDayOfMonth() == d.getDayOfMonth()
&& jd.getTimeOfDay() < d.getTimeOfDay()) {
jd.setMonth(n + 1);
jd.setDayOfMonth(d.getDayOfMonth() + 1);
jcal.normalize(jd);
// Month may have changed by the normalization.
n = jd.getMonth() - 1;
}
set(DAY_OF_MONTH, jd.getDayOfMonth());
}
set(MONTH, n);
} else {
int mon = (internalGet(MONTH) + amount) % 12;
if (mon < 0) {
mon += 12;
}
set(MONTH, mon);
// Keep the day of month in the range. We
// don't want to spill over into the next
// month; e.g., we don't want jan31 + 1 mo ->
// feb31 -> mar3.
int monthLen = monthLength(mon);
if (internalGet(DAY_OF_MONTH) > monthLen) {
set(DAY_OF_MONTH, monthLen);
}
}
} else {
int eraIndex = getEraIndex(jdate);
CalendarDate transition = null;
if (jdate.getYear() == 1) {
transition = eras[eraIndex].getSinceDate();
min = transition.getMonth() - 1;
} else {
if (eraIndex < eras.length - 1) {
transition = eras[eraIndex + 1].getSinceDate();
if (transition.getYear() == jdate.getNormalizedYear()) {
max = transition.getMonth() - 1;
if (transition.getDayOfMonth() == 1) {
max--;
}
}
}
}
if (min == max) {
// The year has only one month. No need to
// process further. (Showa Gan-nen (year 1)
// and the last year have only one month.)
return;
}
int n = getRolledValue(internalGet(field), amount, min, max);
set(MONTH, n);
if (n == min) {
if (!(transition.getMonth() == BaseCalendar.JANUARY
&& transition.getDayOfMonth() == 1)) {
if (jdate.getDayOfMonth() < transition.getDayOfMonth()) {
set(DAY_OF_MONTH, transition.getDayOfMonth());
}
}
} else if (n == max && (transition.getMonth() - 1 == n)) {
int dom = transition.getDayOfMonth();
if (jdate.getDayOfMonth() >= dom) {
set(DAY_OF_MONTH, dom - 1);
}
}
}
return;
}
case WEEK_OF_YEAR:
{
int y = jdate.getNormalizedYear();
max = getActualMaximum(WEEK_OF_YEAR);
set(DAY_OF_WEEK, internalGet(DAY_OF_WEEK)); // update stamp[field]
int woy = internalGet(WEEK_OF_YEAR);
int value = woy + amount;
if (!isTransitionYear(jdate.getNormalizedYear())) {
int year = jdate.getYear();
if (year == getMaximum(YEAR)) {
max = getActualMaximum(WEEK_OF_YEAR);
} else if (year == getMinimum(YEAR)) {
min = getActualMinimum(WEEK_OF_YEAR);
max = getActualMaximum(WEEK_OF_YEAR);
if (value > min && value < max) {
set(WEEK_OF_YEAR, value);
return;
}
}
// If the new value is in between min and max
// (exclusive), then we can use the value.
if (value > min && value < max) {
set(WEEK_OF_YEAR, value);
return;
}
long fd = cachedFixedDate;
// Make sure that the min week has the current DAY_OF_WEEK
long day1 = fd - (7 * (woy - min));
if (year != getMinimum(YEAR)) {
if (gcal.getYearFromFixedDate(day1) != y) {
min++;
}
} else {
CalendarDate d = jcal.getCalendarDate(Long.MIN_VALUE, getZone());
if (day1 < jcal.getFixedDate(d)) {
min++;
}
}
// Make sure the same thing for the max week
fd += 7 * (max - internalGet(WEEK_OF_YEAR));
if (gcal.getYearFromFixedDate(fd) != y) {
max--;
}
break;
}
// Handle transition here.
long fd = cachedFixedDate;
long day1 = fd - (7 * (woy - min));
// Make sure that the min week has the current DAY_OF_WEEK
LocalGregorianCalendar.Date d = getCalendarDate(day1);
if (!(d.getEra() == jdate.getEra() && d.getYear() == jdate.getYear())) {
min++;
}
// Make sure the same thing for the max week
fd += 7 * (max - woy);
jcal.getCalendarDateFromFixedDate(d, fd);
if (!(d.getEra() == jdate.getEra() && d.getYear() == jdate.getYear())) {
max--;
}
// value: the new WEEK_OF_YEAR which must be converted
// to month and day of month.
value = getRolledValue(woy, amount, min, max) - 1;
d = getCalendarDate(day1 + value * 7);
set(MONTH, d.getMonth() - 1);
set(DAY_OF_MONTH, d.getDayOfMonth());
return;
}
case WEEK_OF_MONTH:
{
boolean isTransitionYear = isTransitionYear(jdate.getNormalizedYear());
// dow: relative day of week from the first day of week
int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
if (dow < 0) {
dow += 7;
}
long fd = cachedFixedDate;
long month1; // fixed date of the first day (usually 1) of the month
int monthLength; // actual month length
if (isTransitionYear) {
month1 = getFixedDateMonth1(jdate, fd);
monthLength = actualMonthLength();
} else {
month1 = fd - internalGet(DAY_OF_MONTH) + 1;
monthLength = jcal.getMonthLength(jdate);
}
// the first day of week of the month.
long monthDay1st = jcal.getDayOfWeekDateOnOrBefore(month1 + 6,
getFirstDayOfWeek());
// if the week has enough days to form a week, the
// week starts from the previous month.
if ((int)(monthDay1st - month1) >= getMinimalDaysInFirstWeek()) {
monthDay1st -= 7;
}
max = getActualMaximum(field);
// value: the new WEEK_OF_MONTH value
int value = getRolledValue(internalGet(field), amount, 1, max) - 1;
// nfd: fixed date of the rolled date
long nfd = monthDay1st + value * 7 + dow;
// Unlike WEEK_OF_YEAR, we need to change day of week if the
// nfd is out of the month.
if (nfd < month1) {
nfd = month1;
} else if (nfd >= (month1 + monthLength)) {
nfd = month1 + monthLength - 1;
}
set(DAY_OF_MONTH, (int)(nfd - month1) + 1);
return;
}
case DAY_OF_MONTH:
{
if (!isTransitionYear(jdate.getNormalizedYear())) {
max = jcal.getMonthLength(jdate);
break;
}
// TODO: Need to change the spec to be usable DAY_OF_MONTH rolling...
// Transition handling. We can't change year and era
// values here due to the Calendar roll spec!
long month1 = getFixedDateMonth1(jdate, cachedFixedDate);
// It may not be a regular month. Convert the date and range to
// the relative values, perform the roll, and
// convert the result back to the rolled date.
int value = getRolledValue((int)(cachedFixedDate - month1), amount,
0, actualMonthLength() - 1);
LocalGregorianCalendar.Date d = getCalendarDate(month1 + value);
assert getEraIndex(d) == internalGetEra()
&& d.getYear() == internalGet(YEAR) && d.getMonth()-1 == internalGet(MONTH);
set(DAY_OF_MONTH, d.getDayOfMonth());
return;
}
case DAY_OF_YEAR:
{
max = getActualMaximum(field);
if (!isTransitionYear(jdate.getNormalizedYear())) {
break;
}
// Handle transition. We can't change year and era values
// here due to the Calendar roll spec.
int value = getRolledValue(internalGet(DAY_OF_YEAR), amount, min, max);
long jan0 = cachedFixedDate - internalGet(DAY_OF_YEAR);
LocalGregorianCalendar.Date d = getCalendarDate(jan0 + value);
assert getEraIndex(d) == internalGetEra() && d.getYear() == internalGet(YEAR);
set(MONTH, d.getMonth() - 1);
set(DAY_OF_MONTH, d.getDayOfMonth());
return;
}
case DAY_OF_WEEK:
{
int normalizedYear = jdate.getNormalizedYear();
if (!isTransitionYear(normalizedYear) && !isTransitionYear(normalizedYear - 1)) {
// If the week of year is in the same year, we can
// just change DAY_OF_WEEK.
int weekOfYear = internalGet(WEEK_OF_YEAR);
if (weekOfYear > 1 && weekOfYear < 52) {
set(WEEK_OF_YEAR, internalGet(WEEK_OF_YEAR));
max = SATURDAY;
break;
}
}
// We need to handle it in a different way around year
// boundaries and in the transition year. Note that
// changing era and year values violates the roll
// rule: not changing larger calendar fields...
amount %= 7;
if (amount == 0) {
return;
}
long fd = cachedFixedDate;
long dowFirst = jcal.getDayOfWeekDateOnOrBefore(fd, getFirstDayOfWeek());
fd += amount;
if (fd < dowFirst) {
fd += 7;
} else if (fd >= dowFirst + 7) {
fd -= 7;
}
LocalGregorianCalendar.Date d = getCalendarDate(fd);
set(ERA, getEraIndex(d));
set(d.getYear(), d.getMonth() - 1, d.getDayOfMonth());
return;
}
case DAY_OF_WEEK_IN_MONTH:
{
min = 1; // after having normalized, min should be 1.
if (!isTransitionYear(jdate.getNormalizedYear())) {
int dom = internalGet(DAY_OF_MONTH);
int monthLength = jcal.getMonthLength(jdate);
int lastDays = monthLength % 7;
max = monthLength / 7;
int x = (dom - 1) % 7;
if (x < lastDays) {
max++;
}
set(DAY_OF_WEEK, internalGet(DAY_OF_WEEK));
break;
}
// Transition year handling.
long fd = cachedFixedDate;
long month1 = getFixedDateMonth1(jdate, fd);
int monthLength = actualMonthLength();
int lastDays = monthLength % 7;
max = monthLength / 7;
int x = (int)(fd - month1) % 7;
if (x < lastDays) {
max++;
}
int value = getRolledValue(internalGet(field), amount, min, max) - 1;
fd = month1 + value * 7 + x;
LocalGregorianCalendar.Date d = getCalendarDate(fd);
set(DAY_OF_MONTH, d.getDayOfMonth());
return;
}
}
set(field, getRolledValue(internalGet(field), amount, min, max));
| public void | setTimeZone(java.util.TimeZone zone)
super.setTimeZone(zone);
// To share the zone by the CalendarDate
jdate.setZone(zone);
|
|