Java 8 DateTime格式日期+偏移量

时间:2017-09-29 11:24:31

标签: java date datetime formatting java-time

我必须为Web服务构建一个XMLGregorianCalendar,期望格式为yyyy-MM-dd+01:00的日期,其中+之后的值是从时区offsett派生的。

到目前为止,我已经尝试过:

DateTimeFormatter formatterDateWithOffset = DateTimeFormatter.ofPattern("yyyy-MM-ddZZ");

XMLGregorianCalendar xcal = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(zonedDateTime.format(formatterDateWithOffset));

但这导致IllegalArgumentExcpetion,因为格式化程序会生成2017-09-29+0200

是否可以为所需格式定义格式字符串?

3 个答案:

答案 0 :(得分:1)

如果您查看DateTimeFormatter上的JavaDoc,您会看到:

  

偏移X和x:这会根据模式字母的数量格式化偏移。一个字母仅输出小时,例如'+01',除非分钟非零,在这种情况下分钟也输出,例如'+0130'。两个字母输出小时和分钟,没有冒号,例如'+0130'。三个字母输出小时和分钟,带有冒号,例如'+01:30'。 ...当要输出的偏移量为零时,模式字母“X”(大写)将输出“Z”,而模式字母“x”(小写)将输出“+00”,“+ 0000”或'+00:00'。

因此DateTimeFormatter formatterDateWithOffset = DateTimeFormatter.ofPattern("yyyy-MM-ddxxx");应该有用。

在我的评论中,我建议使用ZZZZ,因为JavaDoc也暗示了这一点,但它也会添加GMT部分(ZZZZZ似乎也可以工作,即使JavaDoc声明:五个字母输出小时,分钟,可选秒,如果非零,则冒号“)。

答案 1 :(得分:0)

而不是解析你可以创建一个XMLGregorianCalendar实例,传递给它年,月等等:

XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(year, month....)

答案 2 :(得分:0)

正如@Thomas's answer所述,另一种方法是使用xxx(或XXX),explained in javadoc。它们之间的唯一区别是当偏移为零时:XXX格式为Z,而xxx格式为+00:00

Pattern  Count  Equivalent builder methods
-------  -----  --------------------------
XXX      3      appendOffset("+HH:MM","Z")
xxx      3      appendOffset("+HH:MM","+00:00")

无论如何,只需选择其中一个(我已经使用ZonedDateTimeZoneOffset.UTC进行了测试,并且两者都有效:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddXXX");
String str = formatter.format(zonedDateTime);
XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(str);

如果您有ZonedDateTime,则可以更轻松地将其转换为GregorianCalendar,然后将其传递给DatatypeFactory

ZonedDateTime zonedDateTime = ZonedDateTime.now();
GregorianCalendar cal = GregorianCalendar.from(zonedDateTime);
XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);

一个棘手的细节是,当使用上面的String模式(仅使用日期)时,结果将时间字段(小时,分钟,秒和毫秒)设置为零,同时转换为{ {1}}将使用GregorianCalendar

中设置的时间

但您可以将时间设置为午夜,然后再将其转换为ZonedDateTime

GregorianCalendar

这样,结果与使用// convert to calendar (set the time to 00:00:00.000) GregorianCalendar cal = GregorianCalendar.from(zonedDateTime.with(LocalTime.MIDNIGHT)); 相同。