Java8 LocalDateTime to XMLGregorianCalender Remove "+05:30" Portion
Asked Answered
U

2

13

Did like below,

LocalDateTime currentUTCTime = LocalDateTime.now(ZoneId.of("UTC"));
String reqPattern = currentUTCTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS"));
System.out.println("Required pattern: " + reqPattern);
GregorianCalendar calendar = GregorianCalendar.from(currentUTCTime.atZone(ZoneId.systemDefault()));
XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
System.out.println("But Showing As :" + xcal);

I want the output as 2015-06-18 11:59:15:135, but when i set the xcal to a XML tag which takes XMLGregorianCalender, it shows like 2015-06-18T11:59:15.135+05:30.

How can i remove the +05:30 portion?

Unbowed answered 18/6, 2015 at 12:5 Comment(2)
Have you tried DatatypeFactory.newInstance().newXMLGregorianCalendar(currentUTCTime.toString()) using the lexical representation in ISO-8601?Airboat
@Meno Hochschild: No i didnt. But tried now and it works fine. Thank You very Much. Can you please Post this answer so i can mark it as solved and pick it as solution.Unbowed
A
14

Use this code:

LocalDateTime currentUTCTime = LocalDateTime.now(); // using system timezone
String iso = currentUTCTime.toString();
if (currentUTCTime.getSecond() == 0 && currentUTCTime.getNano() == 0) {
    iso += ":00"; // necessary hack because the second part is not optional in XML
}
XMLGregorianCalendar xml =
  DatatypeFactory.newInstance().newXMLGregorianCalendar(iso‌​);

Explanation:

The code makes use of the given factory method expecting a lexicographical representation of a local timestamp in ISO-8601-format. And since a LocalDateTime does not refer to any timezone, its output via toString() cannot contain a timezone offset. Result: XMLGregorianCalendar considers the timezone offset as "not set".

Correction:

The original code did not especially bother about the ISO-variant of formatted output of currentUTCTime.toString(). However, the java.time-API produces an output without seconds or nanoseconds if those parts are equal to zero. This is perfectly legal in ISO, but the W3C-consortium has made the second part non-optional. And the class XMLGregorianCalendar closely follows this deviating spec. Therefore the shown hack above using simple string concatenation in this special edge case. Thanks a lot to @Dave's comment. By the way, using currentUTCTime.format(DateTimeFormatter.ISO_DATE_TIME) as suggested in this comment is also possible (instead of the shown hack).

Airboat answered 18/6, 2015 at 12:34 Comment(3)
This doesn't work. What you want is DatatypeFactory.newInstance().newXMLGregorianCalendar(currentUTCTime.format(DateTimeFormatter.ISO_DATE_TIME)). XMLGregorianCalendar.newXMLGregorianCalendar(String) requires that its argument have the seconds populated. If seconds == 0 LocalDateTime.toString() will omit the seconds and its preceding : separator completely causing the calendar factory method to throw an IllegalArgumentException.Acescent
@Dave Have now adjusted my answer.Airboat
It would be better to use a formatter than the if statement hackCoppersmith
H
0

Since the factory-method newXMLGregorianCalendar(String lexicalRepresentation) needs a String as a lexical representation, an easy and elegant way is using an ISO formatter like DateTimeFormatter.ISO_DATE_TIME or DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").

String s = DateTimeFormatter.ISO_DATE_TIME.format(localDateTime);
XMLGregorianCalendar xml = DatatypeFactory.newInstance().newXMLGregorianCalendar(s);
Hairspring answered 24/4 at 17:42 Comment(4)
What is different to the already given answer by Meno?Eclectic
Using the formatter is more elegant than the IF statement.Hairspring
I got the solution on my own. Then I found this thread so I added it because the code was better. Now it is visible as the answer and anybody can copy it.Hairspring
Your comments support your code as explanation, so it's worth adding it (see my edit).Eclectic

© 2022 - 2024 — McMap. All rights reserved.