2

我有一个字符串日期,我正在转换为XMLGregorianCalendar. 下面的代码将其转换为没有错误。但是,我将日期传递给的系统会收到下面报告的错误。

以下XMLGregorianCalendar作品:

在此处输入图像描述

以下XMLGregorianCalendar不起作用(下面的代码将其转换为此):

在此处输入图像描述

问题

如何将字符串转换为所需的格式?

 public static void main(String []args){
    try {
        String commenceTOString = "2021-06-30 05:00:00";
        java.util.Date dateCommence = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(commenceTOString);
        System.out.println(dateCommence);
        java.util.GregorianCalendar c = new java.util.GregorianCalendar();
        c.setTime(dateCommence);
        
        javax.xml.datatype.XMLGregorianCalendar commence = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
        System.out.println(commence);

    } catch (Exception e) {
        e.printStackTrace();
    }
 }

错误

E:消息验证失败。错误:[cvc-pattern-valid:值 '2021-06-30T06:30:00.000+02:00' 对于模式 '((((((0[1-9])|(1 [0-2]))-((0[1-9])|(1\d)|(2[0-9])))|((((0[13578])|(1[02] ))-31)|(((0[1,3-9])|(1[0-2]))-30)))|(((19|20)(([02468][048]) |([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((( (0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|(((( 0[13578])|(1[02]))-31)|(((0[1,3-9])|(1[0-2]))-(29|30)))))T ([0-1][0-9]|[2][0-3])(:([0-5][0-9])){1,2}' 对于类型 'dateTime'.cvc- attribute.3:元素“FlightSegment”上属性“DepartureDateTime”的值“2021-06-30T06:30:00.000+02:00”相对于其类型“dateTime”无效。]。http://www.elleipsis.com/booking/exception/35a8ac87-6743-4719-9504-a8a17a1a0471

4

2 回答 2

1

有很多方法可以做到这一点。一般来说,我建议您将 java.time 用于日期和时间工作,即使在 java.time 类和XMLGregorianCalendar.

黑客

hack 只是将其编辑T到期望存在的字符串中XMLGregorianCalendar,然后直接解析修改后的字符串。那么我们既不需要 java.time 也不需要Datenor SimpleDateFormat

    String commenceTOString = "2021-06-30 05:00:00";
    XMLGregorianCalendar commence = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(commenceTOString.replace(' ', 'T'));
    System.out.println(commence);

输出:

2021-06-30T05:00:00

通过字符串转换

解析成LocalDateTime,格式化成格式XMLGregorianCalendar知道的字符串,再让DatatypeFactory解析:

    DateTimeFormatter parser = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss");
    
    LocalDateTime dateTime = LocalDateTime.parse(commenceTOString, parser);
    XMLGregorianCalendar commence = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(dateTime.format(formatter));
    System.out.println(commence);

输出和以前一样。

通过数字转换

虽然长了几行,但这是概念上简单的转换:将每个字段从 转移LocalDateTimeXMLGregorianCalendar

    XMLGregorianCalendar commence = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(
                    dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 
                    dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(),
                    DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
    System.out.println(commence);

输出还是一样的。

通过公历转换

我相信这是官方的转换:转换为ZonedDateTimeGregorianCalendar最后转换为XMLGregorianCalendar. 我们需要将不需要的字段设置FIELD_UNDEFINED为与您自己的答案一样。

    ZonedDateTime dateTime = LocalDateTime.parse(commenceTOString, parser)
            .atZone(ZoneOffset.UTC);
    GregorianCalendar gc = GregorianCalendar.from(dateTime);
    XMLGregorianCalendar commence = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gc);
    commence.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
    commence.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
    System.out.println(commence);

关联

Oracle 教程:日期时间解释如何使用 java.time。

于 2021-05-27T15:34:43.797 回答
0

这为我修复了它:(使用DatatypeConstants.FIELD_UNDEFINED

           GregorianCalendar c = new GregorianCalendar();
            c.setTime(dateCommence);
            XMLGregorianCalendar commence = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
            commence.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
            commence.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
于 2021-05-27T13:21:21.267 回答