【问题标题】:Specify the date format in XMLGregorianCalendar在 XMLGregorianCalendar 中指定日期格式
【发布时间】:2012-12-13 04:00:29
【问题描述】:

我想使用XMLGregorianCalendar 格式的日期发送到网络服务。 Web 服务需要yyyy-dd-mm 格式的信息。我使用下面的代码创建一个XMLGregorianCalendar 并将其发送到网络服务。

Date dob = null;
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

try {
    XMLGregorianCalendar date2;
    dob = df.parse("13/06/1983");

    GregorianCalendar c = new GregorianCalendar();
    c.setTimeInMillis(dob.getTime());
    date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    System.out.println(date2);
}
catch(DatatypeConfigurationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
catch(ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

不幸的是,我总是得到1983-06-13T00:00:00.000-04:00 的日期。时间也包含在输出中。是否可以只获取日期?你能帮帮我吗?

【问题讨论】:

    标签: java calendar gregorian-calendar


    【解决方案1】:

    是的,明白了……

    Date dob=null;
    DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
    dob=df.parse( "13/06/1983" );
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTime(dob);
    XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED);
    

    这将给出正确的格式。

    【讨论】:

    • 为什么+1cal.get(Calendar.MONTH)+1
    • 在 java.util.Calendar 中,一月表示为 0,因此每个月都会移动 1。不要问我为什么...人们推荐 Joda Time 适合的地方。 @Manu
    【解决方案2】:

    您不需要指定“SimpleDateFormat”,它很简单: 您必须在不想显示的地方指定常量“DatatypeConstants.FIELD_UNDEFINED”

    GregorianCalendar cal = new GregorianCalendar();
    cal.setTime(new Date());
    XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED);
    

    【讨论】:

    • 在代码上方出现“javax.xml.datatype.DatatypeConfigurationException: Provider org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl not found”错误。请提出建议。
    • 从 Java 8 开始,您应该使用:DatatypeFactory.newInstance().newXMLGregorianCalendar(c.get(Calendar.YEAR), c.get(Calendar.MONTH)+1, c.get(Calendar. DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
    【解决方案3】:

    仅使用 SimpleDateFormat 更简单,无需单独传递所有参数:

        String FORMATER = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    
        DateFormat format = new SimpleDateFormat(FORMATER);
    
        Date date = new Date();
        XMLGregorianCalendar gDateFormatted =
            DatatypeFactory.newInstance().newXMLGregorianCalendar(format.format(date));
    

    完整示例here

    注意:这仅适用于删除最后 2 个字段:毫秒和时区,或使用格式化程序 yyyy-MM-dd 删除整个时间组件。

    【讨论】:

    • 这是最好的答案。
    • 不要将Z 视为文字。它与 UTC 的偏移量为零,这不太可能是正确的。
    【解决方案4】:

    这是任何格式的简单方法。只需将其更改为所需的格式字符串

    XMLGregorianCalendar gregFmt = DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));
    System.out.println(gregFmt);
    

    【讨论】:

    • 最简单的解决方案!
    • 非常简单而绝妙的解决方案。谢谢
    【解决方案5】:

    没有真正理想的转换,但我想提供几个选项。

    java.time

    首先,您应该使用 java.time(现代 Java 日期和时间 API)中的 LocalDate 来解析和保存您的日期。避免使用DateSimpleDateFormat,因为它们存在设计问题并且早已过时。后者尤其是出了名的麻烦。

        DateTimeFormatter originalDateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    
        String dateString = "13/06/1983";
        LocalDate date = LocalDate.parse(dateString, originalDateFormatter);
        System.out.println(date);
    

    输出是:

    1983-06-13

    你需要更进一步吗? LocalDate.toString() 生成您询问的格式。

    格式化和解析

    假设您确实需要XMLGregorianCalendar,第一个也是最简单的转换选项是:

        XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance()
                .newXMLGregorianCalendar(date.toString());
        System.out.println(xmlDate);
    

    1983-06-13

    格式化为字符串并将其解析回来对我来说是一种浪费,但正如我所说,这很容易,而且我认为结果符合预期不会有任何意外。

    分别传递年、月和日

        XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance()
                .newXMLGregorianCalendarDate(date.getYear(), date.getMonthValue(),
                        date.getDayOfMonth(), DatatypeConstants.FIELD_UNDEFINED);
    

    结果和以前一样。我们需要明确表示我们不想要时区偏移(这是DatatypeConstants.FIELD_UNDEFINED 指定的)。如果有人想知道,LocalDateXMLGregorianCalendar 都以人类的方式计算月份,所以没有加或减 1。

    通过公历转换

    我只给你看这个选项,因为我以某种方式认为它是官方方式:将LocalDate转换为ZonedDateTime,然后转换为GregorianCalendar,最后转换为XMLGregorianCalendar

        ZonedDateTime dateTime = date.atStartOfDay(ZoneOffset.UTC);
        GregorianCalendar gregCal = GregorianCalendar.from(dateTime);
        XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance()
                .newXMLGregorianCalendar(gregCal);
        xmlDate.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
                DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
        xmlDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
    

    我喜欢转换本身,因为我们既不需要使用字符串也不需要传递单个字段(注意以正确的顺序进行)。我不喜欢的是我们必须传递一天中的时间和时区偏移量,然后手动清除这些字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多