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

converting from GMT to local time gives wrong result when DST is in effect

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      1.1.4
    • CPU:
      generic
    • OS:
      solaris_2.5.1
    • Verification:
      Not verified

      Description

      In our calendaring application, all times are stored as GMT based time.
      When converting the GMT time to the local time, say to PST time, I
      am using the following algorithm:
      java.util.Calendar calendar = java.util.Calendar.getInstance();
      calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
      calendar.set(year, month-1, date, hrs, min, sec);
      return calendar.getTime();
      However, the result is wrong when the time falls in the PST daylight
      saving time zone.

      The following test class shows the proble:

      % cat test.java

      import java.util.*;

      public class test {

          public static void main(String args[]) {

      if (args.length < 6) {
      System.out.println("usage: java test year month date hour
      min sec");
      return;
      }

      Date date;
      Calendar gmtcal = Calendar.getInstance();
      gmtcal.setTimeZone(TimeZone.getTimeZone("GMT"));
      gmtcal.set(Integer.parseInt(args[0]),
      Integer.parseInt(args[1])-1,
      Integer.parseInt(args[2]),
      Integer.parseInt(args[3]),
      Integer.parseInt(args[4]),
      Integer.parseInt(args[5]));

      date = gmtcal.getTime();
      System.out.println("date = "+date);

      Calendar cal = Calendar.getInstance();
      cal.setTime(date);

      int offset = cal.getTimeZone().getOffset(
      cal.get(java.util.Calendar.ERA),
      cal.get(java.util.Calendar.YEAR),
      cal.get(java.util.Calendar.MONTH),
      cal.get(java.util.Calendar.DATE),
      cal.get(java.util.Calendar.DAY_OF_WEEK),
      cal.get(java.util.Calendar.MILLISECOND));

      System.out.println("offset for "+date+"= "+(offset/1000/60/60) + "hr");

          }

      }

      Sample output 1:
      % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 1 1 12 0 0
      date = Wed Jan 01 04:00:00 PST 1997
      offset for Wed Jan 01 04:00:00 PST 1997= -8hr

      Sample output 2:
      % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 4 16 18 30 0
      date = Wed Apr 16 10:30:00 PDT 1997
      offset for Wed Apr 16 10:30:00 PDT 1997= -7hr

      Note that in sample output 2 according to the offset, the gmt time
      of the result would be 1997 4 16 17 30 0 which is different from the
      input of 1997 4 16 18 30 0.

      To work around the above problem, I use the following workaround to
      do the conversion:

      % cat testwkaround.java

      import java.util.*;

      public class testwkaround {

          public static void main(String args[]) {

      if (args.length < 6) {
                      System.out.println("usage: java testnewbug year month date hour
      min sec");
                      return;
              }

      java.util.Calendar calendar = java.util.Calendar.getInstance();
              calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
              calendar.set(Integer.parseInt(args[0]),
      Integer.parseInt(args[1])-1,
      Integer.parseInt(args[2]),
      Integer.parseInt(args[3]),
      Integer.parseInt(args[4]),
      Integer.parseInt(args[5]));
              calendar.setTimeZone(TimeZone.getDefault());
       
              // get the timezone offset for the given date
              int offset = calendar.getTimeZone().getOffset(
                                      calendar.get(java.util.Calendar.ERA),
                                      calendar.get(java.util.Calendar.YEAR),
                                      calendar.get(java.util.Calendar.MONTH),
                                      calendar.get(java.util.Calendar.DATE),
                                      calendar.get(java.util.Calendar.DAY_OF_WEEK),
                                      calendar.get(java.util.Calendar.MILLISECOND));

              // adjust the date with calculated offset
              calendar.set(Integer.parseInt(args[0]),
      Integer.parseInt(args[1])-1,
      Integer.parseInt(args[2]),
      Integer.parseInt(args[3]),
      Integer.parseInt(args[4]),
      Integer.parseInt(args[5]));
       
              // needed to make Calendar compute the time after set
              calendar.getTime();
              calendar.add(java.util.Calendar.MILLISECOND, offset);
       
              System.out.println("date = "+gmtcal.getTime());
          }
      }

      However, with the above workaround, the resulting time is off by
      1 hr ahead/behind during the week when we transition into/out of DST
      as shown by the following output:

      % /usr/local/java/jdk1.1.3/solaris/bin/java testwkaround 1997 1 1 12 0 0
      date = Wed Jan 01 04:00:00 PST 1997 <-- correct

      % /usr/local/java/jdk1.1.3/solaris/bin/java testwkaround 1997 7 15 17 0 0
      date = Tue Jul 15 10:00:00 PDT 1997 <-- correct

      % /usr/local/java/jdk1.1.3/solaris/bin/java testwkaround 1997 4 6 18 30 0
      date = Sun Apr 06 10:30:00 PDT 1997 <-- 1hr ahead of correct time of
      11:30am

      % /usr/local/java/jdk1.1.3/solaris/bin/java testwkaround 1997 10 27 17 0 0
      date = Mon Oct 27 10:00:00 PST 1997 <-- 1hr behind correct time of
      9:00 am




        Attachments

          Activity

            People

            Assignee:
            nlindenbsunw Norbert Lindenberg (Inactive)
            Reporter:
            duke J. Duke (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: