Index: src/test/java/tests/api/java/util/GregorianCalendarTest.java =================================================================== --- src/test/java/tests/api/java/util/GregorianCalendarTest.java (revision 496237) +++ src/test/java/tests/api/java/util/GregorianCalendarTest.java (working copy) @@ -642,6 +642,14 @@ gc.setGregorianChange(date); gc.setTimeInMillis(Date.parse("Dec 24 00:00:01 GMT 2000")); assertEquals(346, gc.get(Calendar.DAY_OF_YEAR)); + + // Regression test for Harmony-3003 + date = new Date(Date.parse("Feb 28 00:00:01 GMT 2000")); + gc = new GregorianCalendar(); + gc.setGregorianChange(date); + gc.setTimeInMillis(Date.parse("Dec 1 00:00:01 GMT 2000")); + assertEquals(1, gc.get(Calendar.DAY_OF_MONTH)); + assertEquals(11, gc.get(Calendar.MONTH)); } /** Index: src/main/java/java/util/GregorianCalendar.java =================================================================== --- src/main/java/java/util/GregorianCalendar.java (revision 495534) +++ src/main/java/java/util/GregorianCalendar.java (working copy) @@ -328,6 +328,9 @@ int dayOfYear = computeYearAndDay(days, timeVal + zoneOffset); fields[DAY_OF_YEAR] = dayOfYear; + if(fields[YEAR] == changeYear && gregorianCutover < timeVal + zoneOffset){ + dayOfYear += currentYearSkew; + } int month = dayOfYear / 32; boolean leapYear = isLeapYear(fields[YEAR]); int date = dayOfYear - daysInYear(leapYear, month); @@ -356,6 +359,9 @@ dayOfYear = computeYearAndDay(days, timeVal - zoneOffset + dstOffset); fields[DAY_OF_YEAR] = dayOfYear; + if(fields[YEAR] == changeYear && gregorianCutover < timeVal - zoneOffset + dstOffset){ + dayOfYear += currentYearSkew; + } month = dayOfYear / 32; leapYear = isLeapYear(fields[YEAR]); date = dayOfYear - daysInYear(leapYear, month); @@ -774,7 +780,13 @@ if (year > changeYear) { days -= ((year - 1901) / 100) - ((year - 1601) / 400); } else { - days += julianSkew; + if(year == changeYear){ + days += currentYearSkew; + }else if(year == changeYear -1){ + days += lastYearSkew; + }else{ + days += julianSkew; + } } return days; } else if (year <= changeYear) { @@ -782,9 +794,8 @@ } return (year - 1970) * 365 + ((year - 1972) / 4) - ((year - 2000) / 100) + ((year - 2000) / 400); - } - + private int daysInMonth() { return daysInMonth(isLeapYear(fields[YEAR]), fields[MONTH]); } @@ -1216,8 +1227,8 @@ isCached = false; int dayOfYear = cal.get(DAY_OF_YEAR); if (dayOfYear < julianSkew) { - currentYearSkew = dayOfYear; - lastYearSkew = julianSkew - dayOfYear; + currentYearSkew = dayOfYear-1; + lastYearSkew = julianSkew - dayOfYear + 1; } else { lastYearSkew = 0; currentYearSkew = julianSkew;