1

I have a DateTimeXmlAdapter that I'm using to convert Joda dates to Strings. It looks as follows:

public class DateTimeXmlAdapter extends XmlAdapter<String, DateTime> {
    private static final String PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";
    private static final DateTimeFormatter formatter = DateTimeFormat.forPattern(PATTERN);

    @Override
    public DateTime unmarshal(String value) {
        return formatter.parseDateTime(value);
    }

    @Override
    public String marshal(DateTime value) {
        return formatter.print(value);
    }
}

This results in the following string in XML:

2014-10-16T18:31:57-0400

However, the endpoint I'm sending this to expects a 'Z' at the end instead of -0400. They recommend converting to UTC so timezone information doesn't need to be sent. Makes sense to me. However, I can't seem to get a 'Z' to be at the end unless I state it literally. As in:

private static final String PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";

The discussion below seems to indicate that adding the Z is not recommended.

Validating Timestamp format yyyy-MM-dd'T'HH:mm:ssZ in java?

It tried changing it to the following, but this results in a date w/o the 'Z'.

public class DateTimeXmlAdapter extends XmlAdapter<String, DateTime> {
    private static final DateTimeFormatter formatter = ISODateTimeFormat.dateHourMinuteSecond().withZoneUTC();

    @Override
    public DateTime unmarshal(String value) {
        return formatter.parseDateTime(value);
    }

    @Override
    public String marshal(DateTime value) {
        return formatter.print(value);
    }
}

Output:

2014-10-17T18:50:43

The endpoint I'm talking to says they need the 'Z' because it indicates zero offset from UTC. What's the proper way to add a 'Z' at the end when using Joda Time and JAXB?

Thanks,

Matt

Community
  • 1
  • 1
Matt Raible
  • 8,187
  • 9
  • 61
  • 120

2 Answers2

1

With Z vs. without Z is a known timezone vs. unknown timezone. See this question:

Semantics of the xsd:dateTime without timezone and its conversion to Date

I'd suggest converting Joda DateTime not to String but to XMLGregorianCalendar which is much more elaborate on the timezone etc. fields. JAXB will then take care of XMLGregorianCalendar marshalling (or unmarshalling).

See:

  • javax.xml.datatype.DatatypeFactory.newInstance()
  • javax.xml.datatype.DatatypeFactory.newXMLGregorianCalendar(year, month, day, hour, minute, second, millisecond, timezone) - set the last one to 0 for Z
Community
  • 1
  • 1
lexicore
  • 42,748
  • 17
  • 132
  • 221
1

The use of method ISODateTimeFormat.dateHourMinuteSecond() is not appropriate because it does not output the offset (in your case this is Z = UTC+00:00). Instead you can use the method dateTimeNoMillis(), and of course you need to change the DateTime-object to UTC-offset:

public class DateTimeXmlAdapter extends XmlAdapter<String, DateTime> {
    private static final DateTimeFormatter formatter = 
        ISODateTimeFormat.dateTimeNoMillis().withZoneUTC();

    @Override
    public DateTime unmarshal(String value) {
        return formatter.parseDateTime(value);
    }

    @Override
    public String marshal(DateTime value) {
        return formatter.print(value);
    }
}

From the documentation:

Returns a formatter that combines a full date and time without millis, separated by a 'T' (yyyy-MM-dd'T'HH:mm:ssZZ). The time zone offset is 'Z' for zero, and of the form '±HH:mm' for non-zero.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126