JDK-6218127 : Ambiguous semantics of Celandar.YEAR in GregorianCalendar
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2005-01-17
  • Updated: 2010-07-29
  • Resolved: 2005-01-18
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.4.2_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
Java HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
java.util.GregorianCalendar uses the field Calendar.YEAR in an ambiguous way. This problem surfaces when dealing with Calendar.WEEK_OF_YEAR.

When setting the week of the year:
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.YEAR, 2003);
        cal.set(Calendar.WEEK_OF_YEAR, 1);

the YEAR field is interpreted together with the WEEK_OF_YEAR field as the year of the WEEK_OF_YEAR value.

When getting the YEAR field again:
        assertEquals(1, cal.get(Calendar.WEEK_OF_YEAR));
        assertEquals(2003, cal.get(Calendar.YEAR));
the YEAR field is interpreted as the year of the date represented by the calendar.

This introduces a modality in two ways:
       * the meaning of YEAR is different when setting and when getting
       * when settingm the meaning of YEAR is different depending if WEEK_OF_YEAR is set or not

The two years are not the same, which can be verified for Monday of week 1 of year 2003 which is Dec 30 2002.
As you can see, there are clearly two semantically differnt years associated with a calendar but they appear intermixed in one single YEAR field currently. On reading the year of the week is completely missing and must be determined with some additional functionality outside the Calendar class (see Workaround).
Thus I request that the year of the date and the year belonging to the WEEK_OF_YEAR be separated into individual fields. A good name would be for instance Calendar.YEAR_OF_WEEK and Calendar.YEAR_OF_DAY. Calendar.YEAR should be deprecated for its ambiguous semantics.

This is related to Bug #4267450 which request a API for reading the year associated with a week in the DateFormat.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This is not something that yields wrong results. It is a flaw in the design of Calendar and GregorianCalendar.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
    public void testKwHandling() {
        TimeZone tz = TimeZone.getTimeZone("GMT");
        DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
        df.setTimeZone(tz);
        
        Calendar cal = new GregorianCalendar(tz);
        cal.set(Calendar.DAY_OF_WEEK,  Calendar.MONDAY);
 
        /* 2003 is interpreted together with week of year */
        cal.set(Calendar.YEAR, 2003);
        cal.set(Calendar.WEEK_OF_YEAR, 1);

        assertEquals("30.12.2002", df.format(cal.getTime()));

        /* year is interpreted as the actual year of the date */
        //assertEquals(2003, Calendar.YEAR);
        assertEquals(2002, Calendar.YEAR);
    }
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
see bug #4267450 for a utility to determine the correct year of a week.
###@###.### 2005-1-17 10:49:35 GMT

Comments
EVALUATION This ambiguous interface was introduces as the 4103271 fix which I believe is a mistake. It's too late to make a correction. Also, the suggested fix isn't possible because we can't change the number of fields without breaking binary compatibility. (i.e., Calendar.FIELD_COUNT defines the array size.) There seems to be no way to fix this problem. ###@###.### 2005-1-18 02:14:29 GMT
18-01-2005