JD Frias
JD Frias

Reputation: 4686

Long To XMLGregorianCalendar and back to Long

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

Answers (2)

Yogendra Singh
Yogendra Singh

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

DNA
DNA

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

Related Questions