Hacks around XMLGregorianCalendar
When generating java classes with xjc from an XML-Schema-File, for all kind of data fields (xs:date, xs:time, xs:dateTime) the XMLGregorianCalendar class is used.
But there are several issues and tricks working with the XMLGregorianCalendar.
Timezone
In case of date and dateTime fields the local default timezone will be taken, when the xml field has no timezone part. i.e.
<date>2010-05-03T10:00:00</date>
Be aware that also the daylight saving time will be considerer. So in Hamburg, Germany, the timezone for the above example will be +02:00.
The timezone for 2010-02-01T10:00:00 is then +01:00.
For xs:time fields in the xml data there is no date part available, so the daylight saving will not be considered. So the timezone for the example below will only + +01:00 in Hamburg, Germany:
Be aware that the timezone has to be considerer always you are dealing with the time part. And xml producers are free to define timezone parts in the date types. i.e.
<date>2010-05-01T10:00:00+04:00</date>
<time>10:00:00Z</time>
So it is wise to normalize all dates to the local timezone and process the request with the local timezone and change the timezone on the response to the required timezone if at all needed:
import java.util.*;public class DateUtil
{
public static Calendar normalize(Calendar c)
{
Calendar cal = GregorianCalendar.getInstance();
cal.setTimeInMillis(c.getTimeInMillis());
return cal;
}
}Usage:
…
XMLGregorianCalendar xgc = ....
Calendar localCal = DateUtil.normalize(xgc.toGregorianCalendar());
...
Time field marshaling without timezone
For many purposes you may wish to suppress parts of the data and time fields to be marshaled and put into the resulting xml data. For example the xml data produced using a XMLGregorianCalendar for a time field will produce among the hour, minute and seconds also the milliseconds and timezone.
In some cases you wish to suppress this informations (i.e. timezone is not relevant).
There are several ideas around this on discussion threads:
But the easiest way is simple and needs only to intialize the fields as
undefined fields. That's all :)
…
public static XMLGregorianCalendar time2xmlgregcal(Calendar c)
{
// only hour, minutes,seconds to be presented for xs:time field
XMLGregorianCalendar xgc = DataTypeFactory.newInstance().newXMLGregorianCalendar(c);
xgc.setMillisecond(DataTypeConstants.FIELD_UNDEFINED);
xgc.setTimeZone(DataTypeConstants.FIELD_UNDEFINED);
xgc.setYear(DataTypeConstants.FIELD_UNDEFINED);
xgc.setMonth(DataTypeConstants.FIELD_UNDEFINED);
xgc.setDay(DataTypeConstants.FIELD_UNDEFINED); return xgc;
}
The example will produce the following data for a xs:time field:
Easy!