Reputation: 4686
I am trying to convert from millisecond time stamp to XMLGregorianCalendar and back, but I seem to be getting wrong results. Am I doing something wrong? It seems I am 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?
Upvotes: 9
Views: 14576
Reputation: 34387
I believe here is the problem. Per documentation, toGregorianCalendar()
relies on the GregorianCalendar
corresponding defaults for conversion when there is any field missing.
If you try:
Date date = new Date();
long ts = date.getTime(); //in place of your input
and run your code, you should find, both to
and from
conversion working fine.
If you want your toGregorianCalendar()
with custom provide inputs as in your example, please use toGregorianCalendar(TimeZone,Locale,Defaults)
and supply the updated defaults to be used in conversion.
Upvotes: -1
Reputation: 42617
Interesting - it works fine for values down to (about) -10000000000000L (and positive values) but larger negative values become inconsistent.
If you print out gc
, xc
, and gc2
, you can see where the problem arises (the 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 out the fields of xc
, you get 1,1,1.
System.out.println(xc.getYear());
System.out.println(xc.getMonth());
System.out.println(xc.getDay());
For gc2
, you get 1,0,1 (which matches xc
, because months are zero-based 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 println
calls changes the output from printing out gc2
! - the time=?
output from gc2
changes to time=-62135568000000
- so some calculation has been triggered by querying the GregorianCalendar
object; the areFieldsSet
property also changes from false
to true
.
The timezones of the two GregorianCalendars are different, but this does not account for the error, which persists even if you set explicit TimeZone and Locale.
Upvotes: 4