使用 Dozer 将 XMLGregorianCalendar 映射到日历
Mapping XMLGregorianCalendar to Calendar with Dozer
先决条件
推土机 5.5.1
代码
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()));
}
}
问题
断言 assertThat(ergebnis.get(Calendar.MONTH), is(erwartung.get(Calendar.MONTH)));
失败。
问题是预期的月份是正确的 (1),但映射的日历包含 (0)。
在 org.dozer.converters.CalendarConverter 中发生以下情况:
...
} else if (XMLGregorianCalendar.class.isAssignableFrom(srcFieldClass)) {
Calendar c = ((XMLGregorianCalendar) srcObj).toGregorianCalendar();
result.setTime(c.getTime());
result.setTimeZone(c.getTimeZone());
}
...
日历 c 包含错误的月份 (= 0)。
调用后的结果 result.setTime(c.getTime());还包含 month = 0.
我应该自己写一个转换器来解决这个问题吗?
以及如何解决问题?
提前致谢。
此致,
最大
为XMLGregorianCalendar
,1月对应1,12月对应12,目前您的测试还可以:
month: 1 to 12 or DatatypeConstants.FIELD_UNDEFINED
但是,Calendar
有从零开始的月份,这意味着 January 对应于 0 和 12月对应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.
也就是说,你的说法是错误的。您正在创建一个 XMLGregorianCalendar
,其中月份为 January,并且您假设它是 February 的断言。 Dozer 中的转换方法看起来是正确的。
你应该做的是使用Calendar
提供的constants,这使得计数是否以0或[=29开头无关紧要=]1:
CALENDAR_EXPECTATION = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.GERMANY);
CALENDAR_EXPECTATION.clear();
CALENDAR_EXPECTATION.set(2015, Calendar.JANUARY, 2, 13, 15, 22);
先决条件
推土机 5.5.1
代码
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()));
}
}
问题
断言 assertThat(ergebnis.get(Calendar.MONTH), is(erwartung.get(Calendar.MONTH)));
失败。
问题是预期的月份是正确的 (1),但映射的日历包含 (0)。
在 org.dozer.converters.CalendarConverter 中发生以下情况:
...
} else if (XMLGregorianCalendar.class.isAssignableFrom(srcFieldClass)) {
Calendar c = ((XMLGregorianCalendar) srcObj).toGregorianCalendar();
result.setTime(c.getTime());
result.setTimeZone(c.getTimeZone());
}
...
日历 c 包含错误的月份 (= 0)。 调用后的结果 result.setTime(c.getTime());还包含 month = 0.
我应该自己写一个转换器来解决这个问题吗? 以及如何解决问题?
提前致谢。
此致,
最大
为XMLGregorianCalendar
,1月对应1,12月对应12,目前您的测试还可以:
month: 1 to 12 or
DatatypeConstants.FIELD_UNDEFINED
但是,Calendar
有从零开始的月份,这意味着 January 对应于 0 和 12月对应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.
也就是说,你的说法是错误的。您正在创建一个 XMLGregorianCalendar
,其中月份为 January,并且您假设它是 February 的断言。 Dozer 中的转换方法看起来是正确的。
你应该做的是使用Calendar
提供的constants,这使得计数是否以0或[=29开头无关紧要=]1:
CALENDAR_EXPECTATION = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.GERMANY);
CALENDAR_EXPECTATION.clear();
CALENDAR_EXPECTATION.set(2015, Calendar.JANUARY, 2, 13, 15, 22);