从java.util.Date转换为javax.xml.datatype.XMLGregorianCalendar的日期更改

时间:2018-09-27 15:46:46

标签: java java.util.date xmlgregoriancalendar

2018年9月27日星期四00:00:00的日期

成为

2018-09-26T22:00:00.000Z

在XMLGregorianCalendar中转换时

通过这种方法:

 public static XMLGregorianCalendar dateToXMLGregorianCalendar(Date date) throws DatatypeConfigurationException{
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTime(date);
    return DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
}

如何避免此日期更改?

Tnx

2 个答案:

答案 0 :(得分:1)

那是相同的日期和时间。

您的第一个日期在时区CEST中,相当于UTC + 2 您的第二个时间戳以Z时区呈现,相当于UTC + 0

因此,两者都表示相同的时间点,但呈现方式不同。

GregorianCalendar提供了一种更改日历时区的方法,如果要在CEST日期和时间中输出,那么我建议您将日历时区更改为该时间。有关API参考,请参见GregorianCalendar.setTimeZone

这还取决于您如何从该日历中检索日期。如果仅打算使用返回纯Java Date对象的.getTime()方法,则可以通过DateTimeFormatter发送此方法,以在所需的任何时区输出日期。

如果您只关心日期的实际“日期”部分,并且不想使其适应各种时区,请查看LocalDate

答案 1 :(得分:1)

根据您的情况和确切要求,这是一个带有许多可能答案的问题。我假设您要使用XMLGregorianCalendar,因为您将在XML文档中使用它的toXMLFormat方法来生成所需的语法。

尝试LocalDate是否起作用

    LocalDate ld = LocalDate.of(2018, Month.SEPTEMBER, 27);
    System.out.println(ld);

这将输出:

  

2018-09-27

如果您需要在XML文档中放入日期,而不是日期和时间以及UTC偏移量,那么这将是合乎逻辑的解决方案。上面是XML中的有效日期格式(请检查底部的链接)。我无法确定XML文档的接收者是否接受它。我会找出是否是我。

您问题中的方法接受一个Date参数。 Date类已经过时并且存在设计问题,因此,如果可以的话,请避免使用它。如果您无法避免,则将其转换为LocalDate,如下所示:

    ZoneId zone = ZoneId.of("Europe/Rome");
    LocalDate ld = date.toInstant().atZone(zone).toLocalDate();

请使用您想要放置欧洲/罗马的所需时区,因为在所有时区中都不会是同一日期。正确的时区是决定您是9月26日还是9月27日的时间。

使用OffsetDateTime

    ZoneId zone = ZoneId.of("Europe/Rome");
    OffsetDateTime odt = LocalDate.of(2018, Month.SEPTEMBER, 27)
                            .atStartOfDay(zone)
                            .toOffsetDateTime();
    System.out.println(odt);
  

2018-09-27T00:00 + 02:00

这几乎也是您从XMLGregorianCalendar获得的语法(XMLGregorianCalendar也可以产生它)。不包括秒和毫秒。再次检查是否可以。如果不是,则将OffsetDateTime格式化为XML的String

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx");
    String dateTimeString = odt.format(formatter);
    System.out.println(dateTimeString);
  

2018-09-27T00:00:00.000 + 02:00

这完全符合您从问题中的XMLGregorianCalendar获得的语法,只是日期和时间没有更改。同样,如果您不能避免接受老式的Date,请转换:

    OffsetDateTime odt = date.toInstant().atZone(zone).toOffsetDateTime();

如果您确实需要XMLGregorianCalendar

    ZoneId zone = ZoneId.of("Europe/Rome");
    ZonedDateTime zdt = date.toInstant().atZone(zone);
    GregorianCalendar cal = GregorianCalendar.from(zdt);
    XMLGregorianCalendar xmlgcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
    System.out.println(xmlgcal);
  

2018-09-27T00:00:00.000 + 02:00

时区说明控制偏移量,从而控制产生的日期和时间。

链接