简体   繁体   English

使用推土机将XMLGregorianCalendar映射到日历

[英]Mapping XMLGregorianCalendar to Calendar with Dozer

Prerequisites 先决条件

Dozer 5.5.1 推土机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))); 断言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). 问题在于预期的月份正确(1),但是映射的Calendar包含(0)。

In org.dozer.converters.CalendarConverter following happens: 在org.dozer.converters.CalendarConverter中,发生以下情况:

...
} 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). 日历c包含错误的月份(= 0)。 And the result after call result.setTime(c.getTime()); 然后调用result.setTime(c.getTime());之后的结果; contains also month = 0. 还包含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: 对于XMLGregorianCalendar一月对应于1十二月对应于12 ,到目前为止您的测试还可以:

month: 1 to 12 or DatatypeConstants.FIELD_UNDEFINED 月: 1到12或DatatypeConstants.FIELD_UNDEFINED

However, Calendar has zero-based months, meaning that January corresponds to 0 and December corresponds to 11 . 但是, Calendar具有从零开始的月份,这意味着January对应于0December对应于11

The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; 阳历和朱利安历中的第一月是一月,即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 . 您正在创建一个XMLGregorianCalendar ,该月份的月份为January ,并且有一个断言(假设您为February) The convert method in Dozer looks correct. 推土机中的convert方法看起来正确。

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提供的常量 ,这使计数以01开头都无关紧要:

CALENDAR_EXPECTATION = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.GERMANY);
CALENDAR_EXPECTATION.clear();
CALENDAR_EXPECTATION.set(2015, Calendar.JANUARY, 2, 13, 15, 22);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM