jdk/src/share/classes/java/util/GregorianCalendar.java
changeset 11130 c7093e306a34
parent 8521 ab64b8d109b8
child 13583 dc0017b1a452
equal deleted inserted replaced
11129:f9ad1aadf3fa 11130:c7093e306a34
   945                     }
   945                     }
   946                 }
   946                 }
   947             }
   947             }
   948 
   948 
   949             if (month >= 0) {
   949             if (month >= 0) {
   950                 set(MONTH, (int) (month % 12));
   950                 set(MONTH, month % 12);
   951             } else {
   951             } else {
   952                 // month < 0
   952                 // month < 0
   953                 month %= 12;
   953                 month %= 12;
   954                 if (month < 0) {
   954                 if (month < 0) {
   955                     month += 12;
   955                     month += 12;
  1311                     month1 = fd - internalGet(DAY_OF_MONTH) + 1;
  1311                     month1 = fd - internalGet(DAY_OF_MONTH) + 1;
  1312                     monthLength = calsys.getMonthLength(cdate);
  1312                     monthLength = calsys.getMonthLength(cdate);
  1313                 }
  1313                 }
  1314 
  1314 
  1315                 // the first day of week of the month.
  1315                 // the first day of week of the month.
  1316                 long monthDay1st = calsys.getDayOfWeekDateOnOrBefore(month1 + 6,
  1316                 long monthDay1st = BaseCalendar.getDayOfWeekDateOnOrBefore(month1 + 6,
  1317                                                                      getFirstDayOfWeek());
  1317                                                                            getFirstDayOfWeek());
  1318                 // if the week has enough days to form a week, the
  1318                 // if the week has enough days to form a week, the
  1319                 // week starts from the previous month.
  1319                 // week starts from the previous month.
  1320                 if ((int)(monthDay1st - month1) >= getMinimalDaysInFirstWeek()) {
  1320                 if ((int)(monthDay1st - month1) >= getMinimalDaysInFirstWeek()) {
  1321                     monthDay1st -= 7;
  1321                     monthDay1st -= 7;
  1322                 }
  1322                 }
  1405                 amount %= 7;
  1405                 amount %= 7;
  1406                 if (amount == 0) {
  1406                 if (amount == 0) {
  1407                     return;
  1407                     return;
  1408                 }
  1408                 }
  1409                 long fd = getCurrentFixedDate();
  1409                 long fd = getCurrentFixedDate();
  1410                 long dowFirst = calsys.getDayOfWeekDateOnOrBefore(fd, getFirstDayOfWeek());
  1410                 long dowFirst = BaseCalendar.getDayOfWeekDateOnOrBefore(fd, getFirstDayOfWeek());
  1411                 fd += amount;
  1411                 fd += amount;
  1412                 if (fd < dowFirst) {
  1412                 if (fd < dowFirst) {
  1413                     fd += 7;
  1413                     fd += 7;
  1414                 } else if (fd >= dowFirst + 7) {
  1414                 } else if (fd >= dowFirst + 7) {
  1415                     fd -= 7;
  1415                     fd -= 7;
  1924 
  1924 
  1925     /**
  1925     /**
  1926      * Returns the millisecond offset from the beginning of this
  1926      * Returns the millisecond offset from the beginning of this
  1927      * year. This Calendar object must have been normalized.
  1927      * year. This Calendar object must have been normalized.
  1928      */
  1928      */
  1929     private final long getYearOffsetInMillis() {
  1929     private long getYearOffsetInMillis() {
  1930         long t = (internalGet(DAY_OF_YEAR) - 1) * 24;
  1930         long t = (internalGet(DAY_OF_YEAR) - 1) * 24;
  1931         t += internalGet(HOUR_OF_DAY);
  1931         t += internalGet(HOUR_OF_DAY);
  1932         t *= 60;
  1932         t *= 60;
  1933         t += internalGet(MINUTE);
  1933         t += internalGet(MINUTE);
  1934         t *= 60;
  1934         t *= 60;
  2483                     if (weekOfYear >= 52) {
  2483                     if (weekOfYear >= 52) {
  2484                         long nextJan1 = fixedDateJan1 + 365;
  2484                         long nextJan1 = fixedDateJan1 + 365;
  2485                         if (cdate.isLeapYear()) {
  2485                         if (cdate.isLeapYear()) {
  2486                             nextJan1++;
  2486                             nextJan1++;
  2487                         }
  2487                         }
  2488                         long nextJan1st = calsys.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
  2488                         long nextJan1st = BaseCalendar.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
  2489                                                                             getFirstDayOfWeek());
  2489                                                                                   getFirstDayOfWeek());
  2490                         int ndays = (int)(nextJan1st - nextJan1);
  2490                         int ndays = (int)(nextJan1st - nextJan1);
  2491                         if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
  2491                         if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
  2492                             // The first days forms a week in which the date is included.
  2492                             // The first days forms a week in which the date is included.
  2493                             weekOfYear = 1;
  2493                             weekOfYear = 1;
  2494                         }
  2494                         }
  2516                     } else {
  2516                     } else {
  2517                         nextJan1 = gregorianCutoverDate;
  2517                         nextJan1 = gregorianCutoverDate;
  2518                         calForJan1 = gcal;
  2518                         calForJan1 = gcal;
  2519                     }
  2519                     }
  2520 
  2520 
  2521                     long nextJan1st = calForJan1.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
  2521                     long nextJan1st = BaseCalendar.getDayOfWeekDateOnOrBefore(nextJan1 + 6,
  2522                                                                             getFirstDayOfWeek());
  2522                                                                               getFirstDayOfWeek());
  2523                     int ndays = (int)(nextJan1st - nextJan1);
  2523                     int ndays = (int)(nextJan1st - nextJan1);
  2524                     if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
  2524                     if (ndays >= getMinimalDaysInFirstWeek() && fixedDate >= (nextJan1st - 7)) {
  2525                         // The first days forms a week in which the date is included.
  2525                         // The first days forms a week in which the date is included.
  2526                         weekOfYear = 1;
  2526                         weekOfYear = 1;
  2527                     }
  2527                     }
  2541      *
  2541      *
  2542      * @param fixedDay1 the fixed date of the first day of the period
  2542      * @param fixedDay1 the fixed date of the first day of the period
  2543      * @param fixedDate the fixed date of the last day of the period
  2543      * @param fixedDate the fixed date of the last day of the period
  2544      * @return the number of weeks of the given period
  2544      * @return the number of weeks of the given period
  2545      */
  2545      */
  2546     private final int getWeekNumber(long fixedDay1, long fixedDate) {
  2546     private int getWeekNumber(long fixedDay1, long fixedDate) {
  2547         // We can always use `gcal' since Julian and Gregorian are the
  2547         // We can always use `gcal' since Julian and Gregorian are the
  2548         // same thing for this calculation.
  2548         // same thing for this calculation.
  2549         long fixedDay1st = gcal.getDayOfWeekDateOnOrBefore(fixedDay1 + 6,
  2549         long fixedDay1st = Gregorian.getDayOfWeekDateOnOrBefore(fixedDay1 + 6,
  2550                                                            getFirstDayOfWeek());
  2550                                                                 getFirstDayOfWeek());
  2551         int ndays = (int)(fixedDay1st - fixedDay1);
  2551         int ndays = (int)(fixedDay1st - fixedDay1);
  2552         assert ndays <= 7;
  2552         assert ndays <= 7;
  2553         if (ndays >= getMinimalDaysInFirstWeek()) {
  2553         if (ndays >= getMinimalDaysInFirstWeek()) {
  2554             fixedDay1st -= 7;
  2554             fixedDay1st -= 7;
  2555         }
  2555         }
  2816                     fixedDate += internalGet(DAY_OF_MONTH);
  2816                     fixedDate += internalGet(DAY_OF_MONTH);
  2817                     fixedDate--;
  2817                     fixedDate--;
  2818                 }
  2818                 }
  2819             } else {
  2819             } else {
  2820                 if (isFieldSet(fieldMask, WEEK_OF_MONTH)) {
  2820                 if (isFieldSet(fieldMask, WEEK_OF_MONTH)) {
  2821                     long firstDayOfWeek = cal.getDayOfWeekDateOnOrBefore(fixedDate + 6,
  2821                     long firstDayOfWeek = BaseCalendar.getDayOfWeekDateOnOrBefore(fixedDate + 6,
  2822                                                                          getFirstDayOfWeek());
  2822                                                                                   getFirstDayOfWeek());
  2823                     // If we have enough days in the first week, then
  2823                     // If we have enough days in the first week, then
  2824                     // move to the previous week.
  2824                     // move to the previous week.
  2825                     if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
  2825                     if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
  2826                         firstDayOfWeek -= 7;
  2826                         firstDayOfWeek -= 7;
  2827                     }
  2827                     }
  2828                     if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
  2828                     if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
  2829                         firstDayOfWeek = cal.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
  2829                         firstDayOfWeek = BaseCalendar.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
  2830                                                                         internalGet(DAY_OF_WEEK));
  2830                                                                                  internalGet(DAY_OF_WEEK));
  2831                     }
  2831                     }
  2832                     // In lenient mode, we treat days of the previous
  2832                     // In lenient mode, we treat days of the previous
  2833                     // months as a part of the specified
  2833                     // months as a part of the specified
  2834                     // WEEK_OF_MONTH. See 4633646.
  2834                     // WEEK_OF_MONTH. See 4633646.
  2835                     fixedDate = firstDayOfWeek + 7 * (internalGet(WEEK_OF_MONTH) - 1);
  2835                     fixedDate = firstDayOfWeek + 7 * (internalGet(WEEK_OF_MONTH) - 1);
  2848                         dowim = internalGet(DAY_OF_WEEK_IN_MONTH);
  2848                         dowim = internalGet(DAY_OF_WEEK_IN_MONTH);
  2849                     } else {
  2849                     } else {
  2850                         dowim = 1;
  2850                         dowim = 1;
  2851                     }
  2851                     }
  2852                     if (dowim >= 0) {
  2852                     if (dowim >= 0) {
  2853                         fixedDate = cal.getDayOfWeekDateOnOrBefore(fixedDate + (7 * dowim) - 1,
  2853                         fixedDate = BaseCalendar.getDayOfWeekDateOnOrBefore(fixedDate + (7 * dowim) - 1,
  2854                                                                    dayOfWeek);
  2854                                                                             dayOfWeek);
  2855                     } else {
  2855                     } else {
  2856                         // Go to the first day of the next week of
  2856                         // Go to the first day of the next week of
  2857                         // the specified week boundary.
  2857                         // the specified week boundary.
  2858                         int lastDate = monthLength(month, year) + (7 * (dowim + 1));
  2858                         int lastDate = monthLength(month, year) + (7 * (dowim + 1));
  2859                         // Then, get the day of week date on or before the last date.
  2859                         // Then, get the day of week date on or before the last date.
  2860                         fixedDate = cal.getDayOfWeekDateOnOrBefore(fixedDate + lastDate - 1,
  2860                         fixedDate = BaseCalendar.getDayOfWeekDateOnOrBefore(fixedDate + lastDate - 1,
  2861                                                                    dayOfWeek);
  2861                                                                             dayOfWeek);
  2862                     }
  2862                     }
  2863                 }
  2863                 }
  2864             }
  2864             }
  2865         } else {
  2865         } else {
  2866             if (year == gregorianCutoverYear && cal == gcal
  2866             if (year == gregorianCutoverYear && cal == gcal
  2875             if (isFieldSet(fieldMask, DAY_OF_YEAR)) {
  2875             if (isFieldSet(fieldMask, DAY_OF_YEAR)) {
  2876                 // Add the offset, then subtract 1. (Make sure to avoid underflow.)
  2876                 // Add the offset, then subtract 1. (Make sure to avoid underflow.)
  2877                 fixedDate += internalGet(DAY_OF_YEAR);
  2877                 fixedDate += internalGet(DAY_OF_YEAR);
  2878                 fixedDate--;
  2878                 fixedDate--;
  2879             } else {
  2879             } else {
  2880                 long firstDayOfWeek = cal.getDayOfWeekDateOnOrBefore(fixedDate + 6,
  2880                 long firstDayOfWeek = BaseCalendar.getDayOfWeekDateOnOrBefore(fixedDate + 6,
  2881                                                                      getFirstDayOfWeek());
  2881                                                                               getFirstDayOfWeek());
  2882                 // If we have enough days in the first week, then move
  2882                 // If we have enough days in the first week, then move
  2883                 // to the previous week.
  2883                 // to the previous week.
  2884                 if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
  2884                 if ((firstDayOfWeek - fixedDate) >= getMinimalDaysInFirstWeek()) {
  2885                     firstDayOfWeek -= 7;
  2885                     firstDayOfWeek -= 7;
  2886                 }
  2886                 }
  2887                 if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
  2887                 if (isFieldSet(fieldMask, DAY_OF_WEEK)) {
  2888                     int dayOfWeek = internalGet(DAY_OF_WEEK);
  2888                     int dayOfWeek = internalGet(DAY_OF_WEEK);
  2889                     if (dayOfWeek != getFirstDayOfWeek()) {
  2889                     if (dayOfWeek != getFirstDayOfWeek()) {
  2890                         firstDayOfWeek = cal.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
  2890                         firstDayOfWeek = BaseCalendar.getDayOfWeekDateOnOrBefore(firstDayOfWeek + 6,
  2891                                                                         dayOfWeek);
  2891                                                                                  dayOfWeek);
  2892                     }
  2892                     }
  2893                 }
  2893                 }
  2894                 fixedDate = firstDayOfWeek + 7 * ((long)internalGet(WEEK_OF_YEAR) - 1);
  2894                 fixedDate = firstDayOfWeek + 7 * ((long)internalGet(WEEK_OF_YEAR) - 1);
  2895             }
  2895             }
  2896         }
  2896         }
  2901     /**
  2901     /**
  2902      * Returns this object if it's normalized (all fields and time are
  2902      * Returns this object if it's normalized (all fields and time are
  2903      * in sync). Otherwise, a cloned object is returned after calling
  2903      * in sync). Otherwise, a cloned object is returned after calling
  2904      * complete() in lenient mode.
  2904      * complete() in lenient mode.
  2905      */
  2905      */
  2906     private final GregorianCalendar getNormalizedCalendar() {
  2906     private GregorianCalendar getNormalizedCalendar() {
  2907         GregorianCalendar gc;
  2907         GregorianCalendar gc;
  2908         if (isFullyNormalized()) {
  2908         if (isFullyNormalized()) {
  2909             gc = this;
  2909             gc = this;
  2910         } else {
  2910         } else {
  2911             // Create a clone and normalize the calendar fields
  2911             // Create a clone and normalize the calendar fields
  2918 
  2918 
  2919     /**
  2919     /**
  2920      * Returns the Julian calendar system instance (singleton). 'jcal'
  2920      * Returns the Julian calendar system instance (singleton). 'jcal'
  2921      * and 'jeras' are set upon the return.
  2921      * and 'jeras' are set upon the return.
  2922      */
  2922      */
  2923     synchronized private static final BaseCalendar getJulianCalendarSystem() {
  2923     synchronized private static BaseCalendar getJulianCalendarSystem() {
  2924         if (jcal == null) {
  2924         if (jcal == null) {
  2925             jcal = (JulianCalendar) CalendarSystem.forName("julian");
  2925             jcal = (JulianCalendar) CalendarSystem.forName("julian");
  2926             jeras = jcal.getEras();
  2926             jeras = jcal.getEras();
  2927         }
  2927         }
  2928         return jcal;
  2928         return jcal;
  2956      * @param date the date for which the first day of the year is
  2956      * @param date the date for which the first day of the year is
  2957      * calculated. The date has to be in the cut-over year (Gregorian
  2957      * calculated. The date has to be in the cut-over year (Gregorian
  2958      * or Julian).
  2958      * or Julian).
  2959      * @param fixedDate the fixed date representation of the date
  2959      * @param fixedDate the fixed date representation of the date
  2960      */
  2960      */
  2961     private final long getFixedDateJan1(BaseCalendar.Date date, long fixedDate) {
  2961     private long getFixedDateJan1(BaseCalendar.Date date, long fixedDate) {
  2962         assert date.getNormalizedYear() == gregorianCutoverYear ||
  2962         assert date.getNormalizedYear() == gregorianCutoverYear ||
  2963             date.getNormalizedYear() == gregorianCutoverYearJulian;
  2963             date.getNormalizedYear() == gregorianCutoverYearJulian;
  2964         if (gregorianCutoverYear != gregorianCutoverYearJulian) {
  2964         if (gregorianCutoverYear != gregorianCutoverYearJulian) {
  2965             if (fixedDate >= gregorianCutoverDate) {
  2965             if (fixedDate >= gregorianCutoverDate) {
  2966                 // Dates before the cutover date don't exist
  2966                 // Dates before the cutover date don't exist
  2982      * @param date the date for which the first day of the month is
  2982      * @param date the date for which the first day of the month is
  2983      * calculated. The date has to be in the cut-over year (Gregorian
  2983      * calculated. The date has to be in the cut-over year (Gregorian
  2984      * or Julian).
  2984      * or Julian).
  2985      * @param fixedDate the fixed date representation of the date
  2985      * @param fixedDate the fixed date representation of the date
  2986      */
  2986      */
  2987     private final long getFixedDateMonth1(BaseCalendar.Date date, long fixedDate) {
  2987     private long getFixedDateMonth1(BaseCalendar.Date date, long fixedDate) {
  2988         assert date.getNormalizedYear() == gregorianCutoverYear ||
  2988         assert date.getNormalizedYear() == gregorianCutoverYear ||
  2989             date.getNormalizedYear() == gregorianCutoverYearJulian;
  2989             date.getNormalizedYear() == gregorianCutoverYearJulian;
  2990         BaseCalendar.Date gCutover = getGregorianCutoverDate();
  2990         BaseCalendar.Date gCutover = getGregorianCutoverDate();
  2991         if (gCutover.getMonth() == BaseCalendar.JANUARY
  2991         if (gCutover.getMonth() == BaseCalendar.JANUARY
  2992             && gCutover.getDayOfMonth() == 1) {
  2992             && gCutover.getDayOfMonth() == 1) {
  3021     /**
  3021     /**
  3022      * Returns a CalendarDate produced from the specified fixed date.
  3022      * Returns a CalendarDate produced from the specified fixed date.
  3023      *
  3023      *
  3024      * @param fd the fixed date
  3024      * @param fd the fixed date
  3025      */
  3025      */
  3026     private final BaseCalendar.Date getCalendarDate(long fd) {
  3026     private BaseCalendar.Date getCalendarDate(long fd) {
  3027         BaseCalendar cal = (fd >= gregorianCutoverDate) ? gcal : getJulianCalendarSystem();
  3027         BaseCalendar cal = (fd >= gregorianCutoverDate) ? gcal : getJulianCalendarSystem();
  3028         BaseCalendar.Date d = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
  3028         BaseCalendar.Date d = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
  3029         cal.getCalendarDateFromFixedDate(d, fd);
  3029         cal.getCalendarDateFromFixedDate(d, fd);
  3030         return d;
  3030         return d;
  3031     }
  3031     }
  3032 
  3032 
  3033     /**
  3033     /**
  3034      * Returns the Gregorian cutover date as a BaseCalendar.Date. The
  3034      * Returns the Gregorian cutover date as a BaseCalendar.Date. The
  3035      * date is a Gregorian date.
  3035      * date is a Gregorian date.
  3036      */
  3036      */
  3037     private final BaseCalendar.Date getGregorianCutoverDate() {
  3037     private BaseCalendar.Date getGregorianCutoverDate() {
  3038         return getCalendarDate(gregorianCutoverDate);
  3038         return getCalendarDate(gregorianCutoverDate);
  3039     }
  3039     }
  3040 
  3040 
  3041     /**
  3041     /**
  3042      * Returns the day before the Gregorian cutover date as a
  3042      * Returns the day before the Gregorian cutover date as a
  3043      * BaseCalendar.Date. The date is a Julian date.
  3043      * BaseCalendar.Date. The date is a Julian date.
  3044      */
  3044      */
  3045     private final BaseCalendar.Date getLastJulianDate() {
  3045     private BaseCalendar.Date getLastJulianDate() {
  3046         return getCalendarDate(gregorianCutoverDate - 1);
  3046         return getCalendarDate(gregorianCutoverDate - 1);
  3047     }
  3047     }
  3048 
  3048 
  3049     /**
  3049     /**
  3050      * Returns the length of the specified month in the specified
  3050      * Returns the length of the specified month in the specified
  3051      * year. The year number must be normalized.
  3051      * year. The year number must be normalized.
  3052      *
  3052      *
  3053      * @see #isLeapYear(int)
  3053      * @see #isLeapYear(int)
  3054      */
  3054      */
  3055     private final int monthLength(int month, int year) {
  3055     private int monthLength(int month, int year) {
  3056         return isLeapYear(year) ? LEAP_MONTH_LENGTH[month] : MONTH_LENGTH[month];
  3056         return isLeapYear(year) ? LEAP_MONTH_LENGTH[month] : MONTH_LENGTH[month];
  3057     }
  3057     }
  3058 
  3058 
  3059     /**
  3059     /**
  3060      * Returns the length of the specified month in the year provided
  3060      * Returns the length of the specified month in the year provided
  3061      * by internalGet(YEAR).
  3061      * by internalGet(YEAR).
  3062      *
  3062      *
  3063      * @see #isLeapYear(int)
  3063      * @see #isLeapYear(int)
  3064      */
  3064      */
  3065     private final int monthLength(int month) {
  3065     private int monthLength(int month) {
  3066         int year = internalGet(YEAR);
  3066         int year = internalGet(YEAR);
  3067         if (internalGetEra() == BCE) {
  3067         if (internalGetEra() == BCE) {
  3068             year = 1 - year;
  3068             year = 1 - year;
  3069         }
  3069         }
  3070         return monthLength(month, year);
  3070         return monthLength(month, year);
  3071     }
  3071     }
  3072 
  3072 
  3073     private final int actualMonthLength() {
  3073     private int actualMonthLength() {
  3074         int year = cdate.getNormalizedYear();
  3074         int year = cdate.getNormalizedYear();
  3075         if (year != gregorianCutoverYear && year != gregorianCutoverYearJulian) {
  3075         if (year != gregorianCutoverYear && year != gregorianCutoverYearJulian) {
  3076             return calsys.getMonthLength(cdate);
  3076             return calsys.getMonthLength(cdate);
  3077         }
  3077         }
  3078         BaseCalendar.Date date = (BaseCalendar.Date) cdate.clone();
  3078         BaseCalendar.Date date = (BaseCalendar.Date) cdate.clone();
  3092 
  3092 
  3093     /**
  3093     /**
  3094      * Returns the length (in days) of the specified year. The year
  3094      * Returns the length (in days) of the specified year. The year
  3095      * must be normalized.
  3095      * must be normalized.
  3096      */
  3096      */
  3097     private final int yearLength(int year) {
  3097     private int yearLength(int year) {
  3098         return isLeapYear(year) ? 366 : 365;
  3098         return isLeapYear(year) ? 366 : 365;
  3099     }
  3099     }
  3100 
  3100 
  3101     /**
  3101     /**
  3102      * Returns the length (in days) of the year provided by
  3102      * Returns the length (in days) of the year provided by
  3103      * internalGet(YEAR).
  3103      * internalGet(YEAR).
  3104      */
  3104      */
  3105     private final int yearLength() {
  3105     private int yearLength() {
  3106         int year = internalGet(YEAR);
  3106         int year = internalGet(YEAR);
  3107         if (internalGetEra() == BCE) {
  3107         if (internalGetEra() == BCE) {
  3108             year = 1 - year;
  3108             year = 1 - year;
  3109         }
  3109         }
  3110         return yearLength(year);
  3110         return yearLength(year);
  3114      * After adjustments such as add(MONTH), add(YEAR), we don't want the
  3114      * After adjustments such as add(MONTH), add(YEAR), we don't want the
  3115      * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
  3115      * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
  3116      * 3, we want it to go to Feb 28.  Adjustments which might run into this
  3116      * 3, we want it to go to Feb 28.  Adjustments which might run into this
  3117      * problem call this method to retain the proper month.
  3117      * problem call this method to retain the proper month.
  3118      */
  3118      */
  3119     private final void pinDayOfMonth() {
  3119     private void pinDayOfMonth() {
  3120         int year = internalGet(YEAR);
  3120         int year = internalGet(YEAR);
  3121         int monthLen;
  3121         int monthLen;
  3122         if (year > gregorianCutoverYear || year < gregorianCutoverYearJulian) {
  3122         if (year > gregorianCutoverYear || year < gregorianCutoverYearJulian) {
  3123             monthLen = monthLength(internalGet(MONTH));
  3123             monthLen = monthLength(internalGet(MONTH));
  3124         } else {
  3124         } else {
  3133 
  3133 
  3134     /**
  3134     /**
  3135      * Returns the fixed date value of this object. The time value and
  3135      * Returns the fixed date value of this object. The time value and
  3136      * calendar fields must be in synch.
  3136      * calendar fields must be in synch.
  3137      */
  3137      */
  3138     private final long getCurrentFixedDate() {
  3138     private long getCurrentFixedDate() {
  3139         return (calsys == gcal) ? cachedFixedDate : calsys.getFixedDate(cdate);
  3139         return (calsys == gcal) ? cachedFixedDate : calsys.getFixedDate(cdate);
  3140     }
  3140     }
  3141 
  3141 
  3142     /**
  3142     /**
  3143      * Returns the new value after 'roll'ing the specified value and amount.
  3143      * Returns the new value after 'roll'ing the specified value and amount.
  3144      */
  3144      */
  3145     private static final int getRolledValue(int value, int amount, int min, int max) {
  3145     private static int getRolledValue(int value, int amount, int min, int max) {
  3146         assert value >= min && value <= max;
  3146         assert value >= min && value <= max;
  3147         int range = max - min + 1;
  3147         int range = max - min + 1;
  3148         amount %= range;
  3148         amount %= range;
  3149         int n = value + amount;
  3149         int n = value + amount;
  3150         if (n > max) {
  3150         if (n > max) {
  3158 
  3158 
  3159     /**
  3159     /**
  3160      * Returns the ERA.  We need a special method for this because the
  3160      * Returns the ERA.  We need a special method for this because the
  3161      * default ERA is CE, but a zero (unset) ERA is BCE.
  3161      * default ERA is CE, but a zero (unset) ERA is BCE.
  3162      */
  3162      */
  3163     private final int internalGetEra() {
  3163     private int internalGetEra() {
  3164         return isSet(ERA) ? internalGet(ERA) : CE;
  3164         return isSet(ERA) ? internalGet(ERA) : CE;
  3165     }
  3165     }
  3166 
  3166 
  3167     /**
  3167     /**
  3168      * Updates internal state.
  3168      * Updates internal state.