【问题标题】:from XMLGregorianCalendar to Date/Calendar adds extra time/unwanted从 XMLGregorianCalendar 到 Date/Calendar 增加了额外的时间/不需要
【发布时间】:2012-11-15 19:29:42
【问题描述】:

我正在开发一个 Web 服务的客户端,该服务公开 (.wsdl) 合同,该合同要求请求参数上的 yyyy-MM-dd 格式为 1,但是基于 .wsdl 自动生成的 POJOS 创建日期属性为输入 XMLGregorianCalendar。


我的问题不是转换为 XMLGregorianCalendar 或从 XMLGregorianCalendar 转换,请参阅下面的实用程序:

public static XMLGregorianCalendar toXMLGregorianCalendar(Calendar c){
 GregorianCalendar gc = new GregorianCalendar();
 gc.setTimeInMillis(c.getTimeInMillis());
 XMLGregorianCalendar xc= null;
try {
    xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
} catch (DatatypeConfigurationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
 return xc;
}

我的问题是从 XMLGregorianCalendar 到 Date/Calendar 在调用 calendar.getTime() 时向我的 yyyy-MM-dd 添加了额外的时间/不需要的数据;

在一个特定的代码段中,我需要从 XMLGregorianCalendar 转到 Date

if (repairOrderType.getCloseDate() != null) {

                LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() BEFORE:"
                        + repairOrderType.getCloseDate());
                String date = repairOrderType.getCloseDate().getYear() + "-"
                        + repairOrderType.getCloseDate().getMonth() + "-"
                        + repairOrderType.getCloseDate().getDay();

                //Approach #1, trying to remove hour,minute,sec values by calendar.clear() method , not successful 
                Calendar calendar = Calendar.getInstance();
                calendar.set(repairOrderType.getCloseDate().getYear(),
                        repairOrderType.getCloseDate().getMonth(),
                        repairOrderType.getCloseDate().getDay());
                calendar.clear(Calendar.HOUR);
                calendar.clear(Calendar.MINUTE);
                calendar.clear(Calendar.SECOND);
                calendar.clear(Calendar.MILLISECOND);



                /*Approach#2 , trying to remove hour,minute,sec values using SimpleDateFormat ,
                 * also not successful. SimpleDateFormat or DateFormat are use to format String output NOT remove internal data
                 *
                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                Calendar calendar = formatter.getCalendar();
                calendar.set(repairOrderType.getCloseDate().getYear(),
                repairOrderType.getCloseDate().getMonth(),
                repairOrderType.getCloseDate().getDay());
                */

                LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() AFTER:"
                        + calendar.getTime());
                repairOrder.setCloseDate(calendar.getTime());

            }

输出:

27-Nov-2012 18:10:39.743 调试 com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() BEFORE:2012-04-30

2012 年 11 月 27 日 18:10:51.413 调试 com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper、processRepairOrders()、repairOrderType.getCloseDate() AFTER:Wed 5 月 30 日 18:00 :00 PDT 2012

正如您在上面看到的,BEFORE 日期是 BEFORE:2012-04-30,AFTER 日期是 5 月 30 日 18:00:00 PDT 2012,不需要的时间是“18:00:00 PDT”。


以下是我发送到服务的实际请求 XML:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns4:VehicleServiceHistoryDetails
            xmlns="urn:tms.toyota.com/Components" xmlns:ns2="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/common/Customer"
            xmlns:ns3="urn:incentives.ari.xxxxxx.com/StandardHeader"
            xmlns:ns4="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/History"
            xmlns:ns5="http://ice.ari.xxxxxx.com/EMF" xmlns:ns6="urn:ari.xxxxxx.com/rtmheader">
            <ns5:ApplicationArea>
                <ns5:CreationDateTime>2012-11-27T18:11:23.071-08:00
                </ns5:CreationDateTime>
                <ns5:Sender />
                <ns5:UserArea />
            </ns5:ApplicationArea>
            <ns4:VehicleServiceHistoryDataArea>
                <ns4:VehicleServiceHistoryHeader>
                    <ns3:TimeStamp>2012-11-27T18:11:23.071-08:00</ns3:TimeStamp>
                    <ns3:SourceSystem>TOO</ns3:SourceSystem>
                    <ns4:SourceKey>TOY1TWXE</ns4:SourceKey>
                </ns4:VehicleServiceHistoryHeader>
                <ns4:VehicleServiceHistory>
                    <ns4:VIN>XXXXXXXXXXXXXXXX</ns4:VIN>
                    <ns4:RepairOrder>
                        <ns2:RepairOrderDealer>
                            <DealerNumber>29059</DealerNumber>
                        </ns2:RepairOrderDealer>
                        <ns2:RepairOrderNumber>0088745</ns2:RepairOrderNumber>
                        <ns2:CloseDate>2012-05-30-07:00</ns2:CloseDate>
                    </ns4:RepairOrder>
                </ns4:VehicleServiceHistory>
            </ns4:VehicleServiceHistoryDataArea>
        </ns4:VehicleServiceHistoryDetails>
    </S:Body>
</S:Envelope>

您可以在 2012-05-30-07:00 的请求 xml 中看到添加了额外的“-07:00”数据,我只想要 2012-05-30。

谢谢

【问题讨论】:

    标签: java web-services jakarta-ee web


    【解决方案1】:

    在 XML 数据类型的上下文中,XMLGregorianCalendar 是通过 javax.xml.datatype.DatatypeFactory 中的工厂方法创建的,该方法似乎有一个名为 newXMLGregorianCalendarDate(int year, int month, int day, int timezone); 的方法。


    所以我创建了一个实用方法:

    public static XMLGregorianCalendar toXMLGregorianCalendarDateOnly(Calendar c){
         GregorianCalendar gc = new GregorianCalendar();
         gc.setTimeInMillis(c.getTimeInMillis());
         XMLGregorianCalendar xc= null;
        try {
            xc = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(gc.get(Calendar.YEAR),Calendar.MONTH,Calendar.DAY_OF_MONTH,DatatypeConstants.FIELD_UNDEFINED);
        } catch (DatatypeConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         return xc;
        }
    

    问题现已解决,我们得到了所需的 yyyy-MM-ddd。

    【讨论】:

    • 正确,缺少月份设置 - xc = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(gregorianCalendar.get(Calendar.YEAR), gregorianCalendar.get(Calendar.MONTH), gregorianCalendar.get(Calendar.DAY_OF_MONTH ), DatatypeConstants.FIELD_UNDEFINED);
    【解决方案2】:

    你也可以这样写,更易读:

    GregorianCalendar gc = new GregorianCalendar();
    gc.setTimeInMillis(c.getTimeInMillis());
    
    XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    calendar.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
    calendar.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
    

    【讨论】:

      【解决方案3】:

      我用下面的代码解决了同样的问题。

      public  static XMLGregorianCalendar toXMLGregorianCalendarWithoutTimeStamp(String date) {
              Date mDate = null;
              GregorianCalendar cal = new GregorianCalendar();
              XMLGregorianCalendar xmlGregorianCalendar;
              DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
              try {
                  mDate = df.parse(date);
                  cal.setTime(mDate);
                  xmlGregorianCalendar = DatatypeFactory.newInstance()
                          .newXMLGregorianCalendarDate(cal.get(Calendar.YEAR),
                                  cal.get(Calendar.MONTH) + 1,
                                  cal.get(Calendar.DAY_OF_MONTH),
                                  DatatypeConstants.FIELD_UNDEFINED);
                  return xmlGregorianCalendar;
      
              } catch (DatatypeConfigurationException e) {
                  LOGGER.error("Error in getCustomerCDRResponse Date Formate Type Configuartion :: " + e);
              } catch (ParseException e) {
                  LOGGER.error("Error in getCustomerCDRResponse Date Parsing :: " + e);
              }
              return null;
          }
      

      【讨论】:

        【解决方案4】:

        试试这个。

        Date dob=null;
            DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
            dob=df.parse( "10/02/2014 11:15:00" );
            GregorianCalendar cal = new GregorianCalendar();
        
            cal.setTime(dob);
        XMLGregorianCalendar xmlDate3 = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),DatatypeConstants.FIELD_UNDEFINED);
        System.out.println(xmlDate3);
        

        【讨论】:

          【解决方案5】:

          如果您使用 javax.xml.bind.Marshaller 来准备 SOAP 主体,那么不需要的行为的根源就在您的 xlmns:ns2 中。 ns2:CloseDate 字段的类型(或其他包含日期和时间的类型):

          {http://www.w3.org/2001/XMLSchema}dateTime
          

          将其更改为(或其他不带小时和分钟的日期类型):

          {http://www.w3.org/2001/XMLSchema}date
          

          如果您不管理此 xlmns,只需接受您的 CloseDate 必须定义时间。如果没有它调用的 web 服务将有不适当的时间声明(我不知道确切的价值,但我打赌 0:00)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-09-15
            • 2020-09-30
            • 1970-01-01
            • 2016-05-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-31
            相关资源
            最近更新 更多