Prerequisites
Dozer 5.5.1
Code
public class Testdata {
public static final Calendar CALENDAR_EXPECTATION;
public static final XMLGregorianCalendar XMLGREGORIANCALENDAR_INPUT;
static {
CALENDAR_EXPECTATION = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.GERMANY);
CALENDAR_EXPECTATION.clear();
CALENDAR_EXPECTATION.set(2015, 1, 2, 13, 15, 22);
XMLGREGORIANCALENDAR_INPUT = XMLGregorianCalendarImpl.createDateTime(2015,
1,
2,
13,
15,
22,
0,
(CALENDAR_EXPECTATION.get(Calendar.ZONE_OFFSET)
+ CALENDAR_EXPECTATION.get(Calendar.DST_OFFSET))
/ (60 * 1000));
}
}
public class MappingTest {
@Autowired
private org.dozer.DozerBeanMapper dozerBeanMapper;
private static x.y.z.ClassToMap classToMap;
@BeforeClass
public static void setupModel() throws Exception {
classToMap = new ClassToMap(Testdata.XMLGREGORIANCALENDAR_INPUT);
}
@Test
public void testTransaktionsInfoToTransaktionsInfo(){
final x.y.MyMappedClass mapped =
dozerBeanMapper.map(classToMap, x.y.MyMappedClass.class);
compareCalendar(mapped.getMyCalendar(), Testdata.CALENDAR_EXPECTATION);
}
private void compareCalendar(Calendar ergebnis, Calendar erwartung) {
assertThat(ergebnis, notNullValue());
assertThat(ergebnis.get(Calendar.YEAR), is(erwartung.get(Calendar.YEAR)));
assertThat(ergebnis.get(Calendar.MONTH), is(erwartung.get(Calendar.MONTH)));
assertThat(ergebnis.get(Calendar.DAY_OF_MONTH), is(erwartung.get(Calendar.DAY_OF_MONTH)));
assertThat(ergebnis.get(Calendar.HOUR), is(erwartung.get(Calendar.HOUR)));
assertThat(ergebnis.get(Calendar.MINUTE), is(erwartung.get(Calendar.MINUTE)));
assertThat(ergebnis.get(Calendar.SECOND), is(erwartung.get(Calendar.SECOND)));
assertThat(ergebnis.get(Calendar.MILLISECOND), is(erwartung.get(Calendar.MILLISECOND)));
assertThat(ergebnis.getTimeZone(), is(erwartung.getTimeZone()));
}
}
Problem
The assert assertThat(ergebnis.get(Calendar.MONTH), is(erwartung.get(Calendar.MONTH)));
fails.
The problem ist that the month in expectation is correct (1) but the mapped Calendar containts (0).
In org.dozer.converters.CalendarConverter following happens:
...
} else if (XMLGregorianCalendar.class.isAssignableFrom(srcFieldClass)) {
Calendar c = ((XMLGregorianCalendar) srcObj).toGregorianCalendar();
result.setTime(c.getTime());
result.setTimeZone(c.getTimeZone());
}
...
Calendar c contains the wrong month (= 0). And the result after call result.setTime(c.getTime()); contains also month = 0.
Should I write my own converter to solve this? And how to solve the problem?
Thanks in advance.
Regards,
Max
For XMLGregorianCalendar
, January corresponds to 1 and December corresponds to 12, your test is OK so far:
month: 1 to 12 or
DatatypeConstants.FIELD_UNDEFINED
However, Calendar
has zero-based months, meaning that January corresponds to 0 and December corresponds to 11.
The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
In other words, your assertion is wrong. You are creating an XMLGregorianCalendar
which has month January, and an assertion where you assume that it is February. The convert method in Dozer looks correct.
What you should do is to use the constants that Calendar
provides, which makes it irrelevant whether the count starts with 0 or 1:
CALENDAR_EXPECTATION = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.GERMANY);
CALENDAR_EXPECTATION.clear();
CALENDAR_EXPECTATION.set(2015, Calendar.JANUARY, 2, 13, 15, 22);