Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4254545

Calendar.roll() and Calendar.add() are broken

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.2.0, 1.2.2, 1.3.0
    • core-libs
    • generic, x86
    • generic, solaris_7, windows_nt

      This is a continuation to bug 4173516 which is closed now.

      Calendar.roll() is broken on field 4 for any day d, 20 <= d <= 31.
      Also, Calendar.add(0) and Calendar.roll() are broken on field 2 for day d=30,31.
      This is using jdk1.2.2_W.

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

      public class y2k_34 {
          static int ierr = 0;

          public static void main(String[] args) {
              int y = 2000, m = Calendar.MARCH, d = 25; // <<-- d=25
              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);
                  }
              }
      System.exit(ierr);
          }

          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));
      ierr = 1;
              }
              else System.out.println("Field " + field + " ok");
          }
      }

      The output log:
      ---------------
      tomboy% /net/ultraowl.eng/export/ultraowl2/jdk12x/sparc/jdk1.2.2_W/bin/java y2k_34
      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 FAIL, expected 2000/2/25 10:45:15.900, got 2000/2/22 10:45:15.900
      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

      -----------

      In the other example for date 1/31/2000 the output is:
      Field 0 ok
      Field 1 ok
      Field 2 FAIL, expected 1999/12/31 10:45:15.900, got 1999/12/28 10:45:15.900
      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 FAIL, expected 1999/12/31 10:45:15.900, got 1999/12/28 10:45:15.900
      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


      anat.kremer@Eng 1999-07-15

      Name: krT82822 Date: 09/04/99


      (note: filed for 1.2.1, but changed to kestrel-beta, since behavior still present in kestrel-beta)

      Compile and run the class to see wrong results.

      import java.awt.*;
      import java.util.*;

      public class TestRoll{
         public static void main( String[] args ){
            Calendar cal = Calendar.getInstance() ;

            //Setting the date as "01 Sep 1999"
            cal.set( 1999, 8, 1 ) ;

            //DEBUG
            System.out.println("Before rolling back : " + cal.getTime() ) ;

            //Going back one day
            cal.roll( Calendar.DATE, false ) ;

            //DEBUG(Expecting "31 Aug 1999")
            System.out.println("After rolling back : " + cal.getTime() ) ;
         }
      }


      java version "1.2.1"
      Classic VM (build JDK-1.2.1-A, native threads)


      Iam expecting the roll() method to rollback to 31 Aug 1999 but it gives 30 Sep 1999, which means it's looping within the same month.

      ------------

      9/4/99 eval1127@eng -- looks like # 4254545, 4248500, etc.:

      results with kestrel-beta (on Solaris -- got same results on NT with "build1.3beta-O"):

      % java TestRoll
      Before rolling back : Wed Sep 01 12:59:31 PDT 1999
      After rolling back : Thu Sep 30 12:59:31 PDT 1999

      % java -version
      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-E)
      Java(TM) HotSpot Client VM (build 1.3beta-E-release, 1.3beta-E-release, interpreted mode)

      (Review ID: 94862)
      ======================================================================

      Name: skT88420 Date: 10/15/99


      When using the roll() method of GregorianCalendar to move forward
      or backward by days, the daytime fields are altered when passing
      through a daylight savings boundary for the Locale.

      That is, a date
      Thu Apr 01 00:00:00 GMT+10:00 1999
      rolled backwards on field Calendar.DAY_OF_YEAR becomes
      Tue Mar 02 01:00:00 GMT+11:00 1999

      It has passed through the change in DST for my locale.
      (East Australia)
      (Review ID: 96610)
      ======================================================================

            ktakahassunw Koushi Takahashi (Inactive)
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: