Search in sources :

Example 6 with CalendarDate

use of sun.util.calendar.CalendarDate in project jdk8u_jdk by JetBrains.

the class JapaneseImperialCalendar method getActualMaximum.

/**
     * 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 <code>DAY_OF_MONTH</code> 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.
     *
     * @param field the calendar field
     * @return the maximum of the given field for the time value of
     * this <code>JapaneseImperialCalendar</code>
     * @see #getMinimum(int)
     * @see #getMaximum(int)
     * @see #getGreatestMinimum(int)
     * @see #getLeastMaximum(int)
     * @see #getActualMinimum(int)
     */
public int getActualMaximum(int field) {
    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 = LocalGregorianCalendar.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;
                    }
                    // # of days in the first week
                    int nDaysFirstWeek = 7 - dayOfWeek;
                    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();
                    // 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;
}
Also used : CalendarDate(sun.util.calendar.CalendarDate) BaseCalendar(sun.util.calendar.BaseCalendar) LocalGregorianCalendar(sun.util.calendar.LocalGregorianCalendar) CalendarDate(sun.util.calendar.CalendarDate)

Example 7 with CalendarDate

use of sun.util.calendar.CalendarDate in project jdk8u_jdk by JetBrains.

the class JapaneseImperialCalendar method roll.

/**
     * 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.
     *
     * <p>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
     * <code>IllegalArgumentException</code> is thrown.
     *
     * @param field the calendar field.
     * @param amount the signed amount to add to <code>field</code>.
     * @exception IllegalArgumentException if <code>field</code> is
     * <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or unknown,
     * or if any calendar fields have out-of-range values in
     * non-lenient mode.
     * @see #roll(int,boolean)
     * @see #add(int,int)
     * @see #set(int,int)
     */
public void roll(int field, int amount) {
    // 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:
            // date, a time zone and the era transitions.
            break;
        case HOUR:
        case HOUR_OF_DAY:
            {
                // 12 or 24 hours
                int unit = max + 1;
                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);
                        // restore PM
                        d.addHours(+12);
                    }
                    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) {
                        // 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);
                // update stamp[field]
                set(DAY_OF_WEEK, internalGet(DAY_OF_WEEK));
                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;
                        }
                    }
                    // (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;
                // fixed date of the first day (usually 1) of the month
                long month1;
                // actual month length
                int monthLength;
                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 = LocalGregorianCalendar.getDayOfWeekDateOnOrBefore(month1 + 6, getFirstDayOfWeek());
                // 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;
                // 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 = LocalGregorianCalendar.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:
            {
                // after having normalized, min should be 1.
                min = 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));
}
Also used : CalendarDate(sun.util.calendar.CalendarDate) CalendarDate(sun.util.calendar.CalendarDate)

Example 8 with CalendarDate

use of sun.util.calendar.CalendarDate in project jdk8u_jdk by JetBrains.

the class JapaneseImperialCalendar method getFixedDateJan1.

/**
     * Returns the fixed date of the first day of the year (usually
     * January 1) before the specified date.
     *
     * @param date the date for which the first day of the year is
     * calculated. The date has to be in the cut-over year.
     * @param fixedDate the fixed date representation of the date
     */
private long getFixedDateJan1(LocalGregorianCalendar.Date date, long fixedDate) {
    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(), Gregorian.JANUARY, 1);
    return gcal.getFixedDate(d);
}
Also used : CalendarDate(sun.util.calendar.CalendarDate) Era(sun.util.calendar.Era)

Example 9 with CalendarDate

use of sun.util.calendar.CalendarDate in project jdk8u_jdk by JetBrains.

the class JapaneseImperialCalendar method computeFields.

/**
     * 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.
     *
     * @param fieldMask a bit mask to specify which fields to change
     * the setting state.
     * @param tzMask a bit mask to specify which time zone offset
     * fields to be used for time calculations
     * @return a new field mask that indicates what field values have
     * actually been set.
     */
private int computeFields(int fieldMask, int tzMask) {
    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);
    // 0-based
    int month = jdate.getMonth() - 1;
    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);
            // Assume AM == 0
            internalSet(AM_PM, hours / 12);
            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);
        // 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) {
                    // future.
                    if (era > HEISEI) {
                        CalendarDate pd = eras[era - 1].getSinceDate();
                        if (normalizedYear == pd.getYear()) {
                            d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
                        }
                    } else {
                        d.setMonth(LocalGregorianCalendar.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 = LocalGregorianCalendar.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(LocalGregorianCalendar.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 = LocalGregorianCalendar.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;
}
Also used : CalendarDate(sun.util.calendar.CalendarDate) LocalGregorianCalendar(sun.util.calendar.LocalGregorianCalendar) ZoneInfo(sun.util.calendar.ZoneInfo) CalendarDate(sun.util.calendar.CalendarDate)

Example 10 with CalendarDate

use of sun.util.calendar.CalendarDate in project jdk8u_jdk by JetBrains.

the class GregorianCalendar method getCalendarDate.

/**
     * Returns a CalendarDate produced from the specified fixed date.
     *
     * @param fd the fixed date
     */
private BaseCalendar.Date getCalendarDate(long fd) {
    BaseCalendar cal = (fd >= gregorianCutoverDate) ? gcal : getJulianCalendarSystem();
    BaseCalendar.Date d = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
    cal.getCalendarDateFromFixedDate(d, fd);
    return d;
}
Also used : BaseCalendar(sun.util.calendar.BaseCalendar) CalendarDate(sun.util.calendar.CalendarDate)

Aggregations

CalendarDate (sun.util.calendar.CalendarDate)17 BaseCalendar (sun.util.calendar.BaseCalendar)5 CalendarSystem (sun.util.calendar.CalendarSystem)4 LocalGregorianCalendar (sun.util.calendar.LocalGregorianCalendar)4 IOException (java.io.IOException)2 Date (java.util.Date)2 DateTimeException (java.time.DateTimeException)1 LocalDate (java.time.LocalDate)1 Era (sun.util.calendar.Era)1 ZoneInfo (sun.util.calendar.ZoneInfo)1