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

(cal) Calendar.getTimeInMillis returns wrong value in different timezone

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P5 P5
    • None
    • 5.0
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.5.0_12"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
      Java HotSpot(TM) Client VM (build 1.5.0_12-b04, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      GrgorianCalendar .getTimeInMillis() method returns wrong value when date is less than 1970 and year range between 1900 and 1945. This happens mostly in Indian standard time zone. It also happens in GMT.

      For ver

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      compile the attached source. and run
      java DateCheck 1700 1945 5


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.*;
      import java.text.SimpleDateFormat;
      import java.util.logging.*;
      import test.MySecs;

      public class DateCheck
      {
          public DateCheck()
          {
              
          }

          //3561-09-24 13:58:06
          //yyyy-MM-dd HH:mm:ss

          public String getDF(int val)
          {
              if(val < 10)
              {
                  return "0"+val;
              }
              else
              {
                  return val+"";
              }
          }
          
          public String getDTF(int year , int month , int day , int hour , int minutes , int second)
          {
              
              String str = "";
              if(year < 10)
              {
                  str ="000"+year;
              }
              else if(year < 100 )
              {
                  str ="00"+year;
              }
              else if(year < 1000 )
              {
                  str ="0"+year;
              }
              else
              {
                  str = year+"";
              }
              str += ("-"+getDF(month+1)+"-"+getDF(day)+" "+getDF(hour)+":"+getDF(minutes)+":"+getDF(second));
              return str;
          }
                               
          public void insertDate(int startYear , int endYear , int step)
              throws Exception
          {
              SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
              Random rd = new Random();
              int counter=0;
              
              StringBuffer matches = new StringBuffer();
              StringBuffer notMatches = new StringBuffer();
              for (int i=startYear ; i<=endYear; i=i+step)
              {
                  int year = i;
                  int month = 0 ;
                  int day =rd.nextInt(20)+1 , hour = rd.nextInt(15), minutes = rd.nextInt(50), secs = rd.nextInt(50);
                  
                  //long time my actual gregorian calendar way
                  long timeByMC = MySecs.getMillis(i, month , day , hour , minutes , secs);
                  // gregorian calendar java implementation
                  java.util.GregorianCalendar gc = new java.util.GregorianCalendar(i, month , day , hour , minutes , secs);
                  long timeByGC = gc.getTimeInMillis();
                  
                  String dtStr= getDTF(i, month , day , hour , minutes , secs);
                  long diff = timeByMC-timeByGC;
                  
                  String str = dtStr+" , "+format.format(new Date(timeByGC)) +" , "+format.format(new Date(timeByMC))+" , "+(diff)+"\n";
                  if(diff != 0)
                  {
                      notMatches.append(str);
                  }
                  else
                  {
                      matches.append(str);
                  }
              }
              
              System.out.println("matches");
              System.out.println(matches);
              System.out.println("notMatches");
              System.out.println(notMatches);
          }
          
          public static void main(String[] args) throws Exception
          {
              DateCheck di = new DateCheck() ;
              di.insertDate(Integer.parseInt(args[0]) , Integer.parseInt(args[1]) , Integer.parseInt(args[2]));
          }
          
      }// DateCheck

      // utllity class to give milklisecond based on date by gregorian calendar.
      //this work only after julian calendard switch year of 1582


      package test;
      import java.util.*;


      public class MySecs {


          private static long timeOfEpoch = -1l;

          private static long getEpoch()
          {
              if(timeOfEpoch == -1l )
              {
                  timeOfEpoch = absVal(1970 , 0, 1 , 0 , 0 , 0);
              }
              return timeOfEpoch;
          }

          private static long getDaysByMonth(long noOfDays , int mth)
          {
              if(mth > Calendar.JANUARY)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.FEBRUARY)
              {
                  noOfDays += 28;
              }
              if(mth > Calendar.MARCH)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.APRIL)
              {
                  noOfDays += 30;
              }
              if(mth > Calendar.MAY)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.JUNE)
              {
                  noOfDays += 30;
              }
              if(mth > Calendar.JULY)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.AUGUST)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.SEPTEMBER)
              {
                  noOfDays += 30;
              }
              if(mth > Calendar.OCTOBER)
              {
                  noOfDays += 31;
              }
              if(mth > Calendar.NOVEMBER)
              {
                  noOfDays += 30;
              }
              return noOfDays;
          }

          private static long absVal(int year , int month , int day , int hour , int minutes , int second)
          {
              long millisVal = hour;
              millisVal *= 60;
      millisVal += minutes;
              millisVal *= 60;
      millisVal += second;
              millisVal *= 1000;
      millisVal += 0;
              boolean currentLeap = (year%4 == 0 && (year%100 != 0 || year %400 == 0) && month > Calendar.FEBRUARY);
              long noOfDays = currentLeap ? 1l : 0l ;
              noOfDays += (day-1);
              int mth = month;
              noOfDays = getDaysByMonth(noOfDays , mth);
              int mYear = year-1;
              double nl = (mYear/4);

              //calculation of leap years
              //year divided by 4 and (divided by 400 or not divided by 100) are alone leap years
              long nofLeap = (long)Math.floor(nl);
              double nl1 = (mYear/400);
              double nl2 = (mYear/100);
              long nlp = ((long)Math.floor(nl2))-((long)Math.floor(nl1));
              
              nofLeap = nofLeap - nlp;
              noOfDays +=nofLeap;
              noOfDays+=(mYear*365);
              millisVal += noOfDays*24*60*60*1000;
              return millisVal;
          }
          
          public static long getMillis(int year , int month , int day , int hour , int minutes , int second)
          {
              long absVal = absVal(year , month , day , hour , minutes , second) ;
              long val = absVal-getEpoch();
              // have a time zone which does has day light savings preferably IST (indian standard time)
              return (val - TimeZone.getDefault().getRawOffset());
          }
      }



      ---------- END SOURCE ----------

            okutsu Masayoshi Okutsu
            okutsu Masayoshi Okutsu
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: