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

GregorianCalendar changes hour field when adding one day

XMLWordPrintable

    • b32
    • generic, x86
    • generic, windows_xp
    • Verified



      Name: erR10175 Date: 11/21/2003


       
        The following method of the class java.util.GregorianCalendar
        
      public void add(int field, int amount)

      changes the HOUR field when the DAY_OF_YEAR field is incremented/decremented.

      The documentation of the method allows to change smaller field which is expected to
      be invariant only if it is out of range:

      "Add rule 2. If a smaller field is expected to be invariant, but it is impossible
      for it to be equal to its prior value because of changes in its minimum or maximum
      after field is changed, then its value is adjusted to be as close as possible to
      its expected value. A smaller field represents a smaller unit of time. HOUR is
      a smaller field than DAY_OF_MONTH. No adjustment is made to smaller fields that are
      not expected to be invariant. The calendar system determines what fields are expected
      to be invariant."

      In the test (see below) the HOUR is invariant when changing DAY_OF_YEAR. So it should
      not change, but there are some dates in time zone "Asia/Novosibirsk" (and some other
      time zones, e.g. AST, ART, AGT) where adding 1 day to the DAY_OF_YEAR changes
      the HOUR field.

      This bug affects new test in JCK 1.5
         api/javax_xml/datatype/Duration/index.html#NormalizeWith[NormalizeWith001]

      The bug is found in jdk1.5.0/beta/b28 on Solaris 2.9, x86 platform
      and reproduces on Solaris 2.8, sparc if the user.timezone property is set to one
      of mentioned above.

      To reproduce the bug compile and run the following code as shown
      in the log below:
      ------------------------------ test.java
      import java.util.GregorianCalendar;
      import java.util.Calendar;
      import java.util.TimeZone;

      public class test {

          public static void main(String [] args) {
              System.out.println("current time zone: " + TimeZone.getDefault());
              int daySteps = 1;
              Calendar startTime = new GregorianCalendar(1583, 0, 1);
              
              int h = 0;
              int m = 0;
              int s = 0;
              for (int i = 0; i <= 1000000; ++i) {
                  Calendar oldTime = (Calendar)startTime.clone();
                  startTime.add(Calendar.DAY_OF_YEAR, daySteps);
                  if (h != startTime.get(Calendar.HOUR_OF_DAY)
                   || m != startTime.get(Calendar.MINUTE)
                   || s != startTime.get(Calendar.SECOND)) {
                      System.out.println("\nstartTime = " + timeStr(oldTime));
                      System.out.println("adding " + daySteps + " days");
                      System.out.println("endTime = " + timeStr(startTime));
                      h = startTime.get(Calendar.HOUR_OF_DAY);
                      m = startTime.get(Calendar.MINUTE);
                      s = startTime.get(Calendar.SECOND);
                  }
              }
          }

          static String timeStr(Calendar c) {
              return c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH)+1-Calendar.JANUARY)
                   + "-" + c.get(Calendar.DAY_OF_MONTH)
                   + " " + c.get(Calendar.HOUR_OF_DAY)
                   + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
          }

      }
      ----------------------------------------------------

      ------------------------------------------------ log
      $javac test.java && java -Duser.timezone=Asia/Novosibirsk -cp . -showversion test
      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b28)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b28, mixed mode)

      current time zone: sun.util.calendar.ZoneInfo[id="Asia/Novosibirsk",offset=21600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=Asia/Novosibirsk,offset=21600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=7200000,startTimeMode=1,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000,endTimeMode=1]]

      startTime = 1900-1-1 0:0:0
      adding 1 days
      endTime = 1900-1-1 23:31:40

      startTime = 1919-12-13 23:31:40
      adding 1 days
      endTime = 1919-12-15 0:0:0

      startTime = 1930-6-20 0:0:0
      adding 1 days
      endTime = 1930-6-21 1:0:0

      startTime = 1991-3-31 1:0:0
      adding 1 days
      endTime = 1991-4-1 0:0:0

      startTime = 1992-1-19 0:0:0
      adding 1 days
      endTime = 1992-1-20 1:0:0

      startTime = 1993-5-22 1:0:0
      adding 1 days
      endTime = 1993-5-23 0:0:0
      ----------------------------------------------------

      ======================================================================

            okutsu Masayoshi Okutsu
            reysunw Rey Rey (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: