Index: modules/luni/src/main/java/java/util/GregorianCalendar.java =================================================================== --- modules/luni/src/main/java/java/util/GregorianCalendar.java (revision 833024) +++ modules/luni/src/main/java/java/util/GregorianCalendar.java (working copy) @@ -545,8 +545,7 @@ fields[MONTH] = month; fields[DATE] = date; fields[DAY_OF_WEEK_IN_MONTH] = (date - 1) / 7 + 1; - fields[WEEK_OF_MONTH] = (date - 1 + mod7(days - date - 2 - - (getFirstDayOfWeek() - 1))) / 7 + 1; + fields[WEEK_OF_MONTH] = computeWeekOfMonth(); int daysFromStart = mod7(days - 3 - (fields[DAY_OF_YEAR] - 1) - (getFirstDayOfWeek() - 1)); int week = (fields[DAY_OF_YEAR] - 1 + daysFromStart) / 7 @@ -564,6 +563,36 @@ } } + /** + * The algorithm first figures out the beginning of the next week. + * The for loop in the method accomplishes the above task. + * Then, it computes the first occurrence + * of the first day of the week in the given month. + * Before the first occurrence if there are more days than + * the minimum required days for first week, + * those days belong to week 1. + * Otherwise, they belong to week 0. + * This method should not be called before + * filds[DATE] is set. + * @return week of the month. The value will be 0 if + * minimum required days for a week are more than the days before + * the first "first day of week" at the beginning of the month. + */ + private int computeWeekOfMonth() { + int firstDay = getFirstDayOfWeek(); + int tempDate = fields[DATE]; + int tempDayOfWeek = DAY_OF_WEEK; + for(int i = 0; i < 7; i++) + if(firstDay == tempDayOfWeek) + break; + else { + tempDate++; + tempDayOfWeek++; + } + int tempFirstWeek = tempDate%7 >= getMinimalDaysInFirstWeek() ? 1 : 0; + return fields[DATE] / 7 + tempFirstWeek; + } + private final void cachedFieldsCheckAndGet(long timeVal, long newTimeMillis, long newTimeMillisAdjusted, int millis, int zoneOffset) {