title: Date change when converting from XMLGregorianCalendar to Calendar
body: <p>When testing out a web service that maps datetime types between systems, I noticed that sending any date before the Gregorian calendar start time resulted in a loss of accuracy when casting to the final type, with the end result always slightly ahead in time in the range of a few days. </p>
  
  <p>I narrowed down the problem to the exact line, but I still can't figure out <em>why</em> it's being cast like so, from the <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/GregorianCalendar.html" rel="nofollow">documentation</a> it states that the Julian calendar is used for datetimes before the Gregorian calendar start: October 15, 1582.</p>
  
  <p>The problem line is at the cast from <code>XMLGregorianCalendar</code> to <code>GregorianCalendar</code>, line 78: <code>calendarDate = argCal.toGregorianCalendar();</code>
  When the time is taken from <code>calendarDate</code> on line 86: <code>cal.setTime(calendarDate.getTime());</code> The time comes back 2 days ahead of what it should be, Jan. 03 instead of Jan. 01, as you'll see from the output in the program below.</p>
  
  <p>Here's a sample program I made to show the casting process end to end:</p>
  
  <pre><code>import java.sql.Date;
  import java.util.Calendar;
  import java.util.GregorianCalendar;
  
  import javax.xml.datatype.DatatypeConfigurationException;
  import javax.xml.datatype.DatatypeFactory;
  import javax.xml.datatype.XMLGregorianCalendar;
  
  
  
  public class TestDateConversions {
  
      public static void main(String[] args)
      {
          TestDateConversions testDates = new TestDateConversions();
          try
          {
              XMLGregorianCalendar testDate1 = DatatypeFactory.newInstance().newXMLGregorianCalendar();
              testDate1.setYear(0001);
              testDate1.setMonth(01);
              testDate1.setDay(01);
              System.out.println("Start date: "+testDate1.toString() +"\n**********************");
  
              testDates.setXMLGregorianCalendar(testDate1);
              System.out.println("\nNull given \n"+ "**********");
              testDates.setXMLGregorianCalendar(null);
          }
          catch(Exception e)
          {
              System.out.println(e);
          }
      }
  
  
      public void setXMLGregorianCalendar(XMLGregorianCalendar argCal)
      {
          GregorianCalendar calendarDate;
          if (argCal != null)
          {
              calendarDate = argCal.toGregorianCalendar();
              System.out.println("XMLGregorianCalendar time: " + argCal.getHour() + ":"+argCal.getMinute()+":"+argCal.getSecond());
              System.out.println("XMLGregorianCalendar time(ms): "+argCal.getMillisecond());
              System.out.println("XMLGregorianCalendar -&gt; GregorianCalendar: "+calendarDate.get(GregorianCalendar.YEAR) + "-"+(calendarDate.get(GregorianCalendar.MONTH)+1) + "-"+calendarDate.get(GregorianCalendar.DAY_OF_MONTH));
              System.out.println("!!!!PROBLEM AREA!!!!");
              Calendar cal = Calendar.getInstance();
              System.out.println("-- New Calendar instance: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH));
              System.out.println("-- Calling Calendar.setTime(GregorianCalendar.getTime())");
              cal.setTime(calendarDate.getTime());
              System.out.println("-- calendarDate.getTime() = " + calendarDate.getTime() + " &lt;-- time is incorrect");
              System.out.println("-- Calendar with time set from GregorianCalendar: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH) + " &lt;-- day is increased here");
              setCalendar(cal);
          }
          else 
          {
              setCalendar(null);
          }
      }
  
      public void setCalendar(Calendar argCal)
      {
          if (argCal != null)
          {
              Date date = new Date(argCal.getTimeInMillis());
              System.out.println("Calendar to Date: "+date);
              setDate(date);
          }
          else
          {
              setDate(null);
          }
  
      }
  
      public void setDate(Date argDate)
      {
          try
          {
              if (argDate == null)
              {
                  Calendar cal  = new GregorianCalendar(1,0,1);
                  Date nullDate = new Date(cal.getTimeInMillis());
                  System.out.println("Null Calendar created: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH));
                  System.out.println("Null Date created: "+nullDate);
              }
              else 
              {
                  System.out.println("Final date type: "+argDate);
              }
          }
          catch (Exception  ex)
          {
              System.out.println(ex);
          }
      }
  }
  </code></pre>