JDK-4173516 : Calendar.roll broken!
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.2.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1998-09-14
  • Updated: 1999-01-15
  • Resolved: 1999-01-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.0 1.2fcsFixed
Related Reports
Relates :  
Relates :  
Relates :  
Description

Name: bb33257			Date: 09/14/98


Calendar.roll() is broken for 4 different fields.  The following
test shows this:

import java.util.*;
import java.text.*;

public class roll {

    public static void main(String[] args) {
        int y = 1997, m = Calendar.FEBRUARY, d = 1;
        int h = 10, M = 45, s = 15, S = 900;
        int limit = 40;
        int field, i;
        GregorianCalendar cal = new GregorianCalendar();

        System.out.println("Testing GregorianCalendar add...");
        for (field=0; field < Calendar.FIELD_COUNT; ++field) {
            if (field != Calendar.ZONE_OFFSET &&
                field != Calendar.DST_OFFSET) {
                cal.clear();
                cal.set(y, m, d, h, M, s);
                cal.set(Calendar.MILLISECOND, S);
                for (i = 0; i < limit; i++) {
                    cal.add(field, 1);
                }
                for (i = 0; i < limit; i++) {
                    cal.add(field, -1);
                }
                checkCalendar(cal, field, y, m, d, h, M, s, S);
            }
        }

        System.out.println("Testing GregorianCalendar roll...");
        for (field=0; field < Calendar.FIELD_COUNT; ++field) {
            if (field != Calendar.ZONE_OFFSET &&
                field != Calendar.DST_OFFSET) {
                cal.clear();
                cal.set(y, m, d, h, M, s);
                cal.set(Calendar.MILLISECOND, S);
                for (i = 0; i < limit; i++) {
                    cal.roll(field, 1);
                }
                for (i = 0; i < limit; i++) {
                    cal.roll(field, -1);
                }
                checkCalendar(cal, field, y, m, d, h, M, s, S);
            }
        }
    }

    static void checkCalendar(Calendar c, int field,
                              int y, int m, int d, int h, int M, int s, int S) {
        if (c.get(Calendar.YEAR) != y ||
            c.get(Calendar.MONTH) != m ||
            c.get(Calendar.DATE) != d ||
            c.get(Calendar.HOUR_OF_DAY) != h ||
            c.get(Calendar.MINUTE) != M ||
            c.get(Calendar.SECOND) != s ||
            c.get(Calendar.MILLISECOND) != S) {
            System.err.println("Field " + field +
                               " FAIL, expected " +
                               y + "/" + (m + 1) + "/" + d +
                               " " + h + ":" + M + ":" + s + "." + S +
                               ", got " + c.get(Calendar.YEAR) +
                               "/" + (c.get(Calendar.MONTH) + 1) +
                               "/" + c.get(Calendar.DATE) +
                               " " + c.get(Calendar.HOUR_OF_DAY) +
                               ":" + c.get(Calendar.MINUTE) +
                               ":" + c.get(Calendar.SECOND) +
                               "." + c.get(Calendar.MILLISECOND));
        }
        else System.out.println("Field " + field + " ok");
    }
}

OUTPUT:

Testing GregorianCalendar add...
Field 0 ok
Field 1 ok
Field 2 ok
Field 3 ok
Field 4 ok
Field 5 ok
Field 6 ok
Field 7 ok
Field 8 ok
Field 9 ok
Field 10 ok
Field 11 ok
Field 12 ok
Field 13 ok
Field 14 ok
Testing GregorianCalendar roll...
Field 0 ok
Field 1 ok
Field 2 ok
Field 3 ok
Field 4 ok
Field 5 ok
Field 6 FAIL, expected 1997/2/1 10:45:15.900, got 1997/3/7 12:6:13.756
Field 7 ok
Field 8 FAIL, expected 1997/2/1 10:45:15.900, got 1995/3/7 14:7:40.540
Field 9 ok
Field 10 FAIL, expected 1997/2/1 10:45:15.900, got 1997/1/30 10:45:15.900
Field 11 FAIL, expected 1997/2/1 10:45:15.900, got 1997/1/30 10:45:15.900
Field 12 ok
Field 13 ok
Field 14 ok
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.2fcs FIXED IN: 1.2fcs INTEGRATED IN: 1.2fcs
14-06-2004

WORK AROUND Name: bb33257 Date: 09/14/98 None! Clients must "roll their own"! ======================================================================
11-06-2004

EVALUATION Fixed by alanl@eng - putback comment: Calendar.roll was broken because certain values were overflowing an int during computation. Fixed this by making the relevant constants longs. Also fixed an improper modulo computation, which was going negative. Added regression test. norbert.lindenberg@Eng 1998-09-18
18-09-1998