简体   繁体   中英

Java 8 DateTime Format Date + Offset

I have to construct a XMLGregorianCalendar for a Webservice which expects a date in the format yyyy-MM-dd+01:00 , where the value after + is derived from the time zone offsett.

So far I have experimented with:

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

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

But this results in an IllegalArgumentExcpetion because the formatter produces 2017-09-29+0200

Is it possible to define a format string for the desired format?

If you have a look at the JavaDoc on DateTimeFormatter you'll see this:

This formats the offset based on the number of pattern letters. 根据模式字母的数量格式化偏移。 One letter outputs just the hour, such as '+01', unless the minute is non-zero in which case the minute is also output, such as '+0130'. Two letters outputs the hour and minute, without a colon, such as '+0130'. Three letters outputs the hour and minute, with a colon, such as '+01:30'. ... Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero, whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.

Thus DateTimeFormatter formatterDateWithOffset = DateTimeFormatter.ofPattern("yyyy-MM-ddxxx"); should work.

In my comment I suggested using ZZZZ because the JavaDoc hinted at that as well but it will add the GMT part too ( ZZZZZ seems to work even though the JavaDoc states: "Five letters outputs the hour, minute, with optional second if non-zero , with colon" ).

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

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

As @Thomas's answer said, one alternative is to use xxx (or XXX ), as explained in javadoc . The only difference between those is when the offset is zero: XXX formats to Z , while xxx formats to +00:00 :

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

Anyway, just choose one of them (I've tested with both, using a ZonedDateTime with ZoneOffset.UTC and both worked):

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

If you have a ZonedDateTime , it's easier to convert it to a GregorianCalendar , and then pass it to your DatatypeFactory :

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

A tricky detail is that, when using the String pattern above (with only the date), the result will have the time fields (hour, minute, second and millisecond) set to zero, while converting to GregorianCalendar will use the time set in the ZonedDateTime .

But you can set the time to midnight before converting it to GregorianCalendar :

// convert to calendar (set the time to 00:00:00.000)
GregorianCalendar cal = GregorianCalendar.from(zonedDateTime.with(LocalTime.MIDNIGHT));

With this, the result will be the same as using the String .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM