Long To XMLGregorianCalendar and back to Long

I am trying to convert from a millisecond timestamp to XMLGregorianCalendar and vice versa, but I seem to get the wrong results. Am I doing something wrong? I seem to be gaining days.

// Time stamp 01-Jan-0001 00:00:00.000 Long ts = -62135740800000L; System.out.println(ts); System.out.println(new Date(ts)); // Sat Jan 01 00:00:00 PST 1 .. Cool! // to Gregorian Calendar GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(ts); // to XML Gregorian Calendar XMLGregorianCalendar xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc); // back to GC GregorianCalendar gc2 = xc.toGregorianCalendar(); // to Timestamp Long newTs = gc2.getTimeInMillis(); System.out.println(newTs); // -62135568000000 .. uh? System.out.println(new Date(newTs)); // Mon Jan 03 00:00:00 PST 1 .. where did the extra days come from? 
+7
source share
2 answers

Interestingly, it works great for values ​​up to (about) -10000000000000L (and positive values), but large negative values ​​become inconsistent.

If you print gc , xc and gc2 , you can see where the problem occurs (conversion from XMLGregorianCalendar to GregorianCalendar

 gc: java.util.GregorianCalendar[time=-62135740800000 ... DAY_OF_WEEK=7 xc: 0001-01-01T08:00:00.000Z gc2: java.util.GregorianCalendar[time=? ... DAY_OF_WEEK=5 

If you print the xc fields, you get 1,1,1.

  System.out.println(xc.getYear()); System.out.println(xc.getMonth()); System.out.println(xc.getDay()); 

For gc2 you will get 1,0,1 (which corresponds to xc , because months are based on a zero value in GregorianCalendar)

  System.out.println(gc2.get(gc2.YEAR)); System.out.println(gc2.get(gc2.MONTH)); System.out.println(gc2.get(gc2.DAY_OF_MONTH)); 

However, adding these 3 calls to println changes the gc2 print gc2 ! - output time=? from gc2 changes to time=-62135568000000 - so some calculations were triggered by a GregorianCalendar object request; the areFieldsSet property also changes from false to true .

The time intervals of the two GregorianCalendars are different, but this does not take into account the error that persists, even if you set the explicit TimeZone and Locale.

+3
source

I think this is a problem. In the documentation, toGregorianCalendar() depends on GregorianCalendar corresponding default values ​​for the conversion if any field is missing.

If you try:

 Date date = new Date(); long ts = date.getTime(); //in place of your input 

and run your code, you should find that both to and from conversions work fine.

If you want your toGregorianCalendar() with user inputs to enter as in your example, use toGregorianCalendar(TimeZone,Locale,Defaults) and set the updated default values ​​that will be used during the conversion.

0
source

All Articles