Skip to content

Instantly share code, notes, and snippets.

@struberg
Last active January 14, 2022 16:53
Show Gist options
  • Save struberg/4baae580d140e83a2e8cab98db97e7be to your computer and use it in GitHub Desktop.
Save struberg/4baae580d140e83a2e8cab98db97e7be to your computer and use it in GitHub Desktop.
Weird JAXB Calendar and Date parsing
/*
I came across a rather nasty timezone glitch with JAXB calendar parsing.
Over here in Europe we have a time offset of +2:00 during summer (CEST) and +1:00 during winter (CET).
That means if we create a Date and Calendar with say 2022-07-23 it will automatically detect this as +2:00 offset.
And on 2022-01-01 it will detect an offset of +1:00. Perfectly fine.
Now let's subtract one day: if I take a Calendar of 2022-04-01_00:00:00 it will detect +2:00.
Subtracting a single day will end up at 2022-03-31_00:00:00 and offset +1:00. Perfectly fine still
But here comes the weird part:
Using JAXB to unmarshal a SOAP Date seems to convert all correctly, but subtracting a single day ends up on 2022-02-30_23:00:00.
The reason behind this is that JAXB doesn't know about the Region you're in. So the timezone is essentially "GMT+02:00".
And it will stay that way.
Whereas if you create a `new GregorianCalendar()` it will have the information TimeZone.ID="Europe/Vienna" for me.
The weird part here is that any converting to e.g. a `java.util.Date` via `Calendar#getTime()` will apply the system default Locale and thus you are 1h off.
*/
GregorianCalendar cal1 = DatumHelper.getCalendarFromString("01.04.2030"); // internally also has a +2:00 offset
cal1.add(Calendar.DAY_OF_MONTH, -1);
Calendar cal2 = javax.xml.bind.DatatypeConverter.parseDate("2030-04-01+02:00"); // JAX-WS by default automatically appends the tz info
cal2.add(Calendar.DAY_OF_MONTH, -1);
"cal1: " + cal1.getTime() + "\ncal2: " + cal2.getTime();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment