Question

I've java schema objects generated from xsd schema using JAXB.

What I'm trying to do is set the values of xml tags using java schema object setter methods and then marshall the java objects. On the final xml generated though, I see that the timestamp generated for xs:datetime types does not have milliseconds.

I'm expecting to see a date like "2013-06-28T01:20:50.000-04:00", all I'm getting is "2013-06-28T01:20:50-04:00" without milliseconds.

Setter call

obj.setTransactionDateTime(getTimestamp("2013-06-28 01:20:50"));

getTimestamp method

public Calendar getTimestamp(String dateStr)
{
    Date returnDate = null;

    if(dateStr == null)
    {
        return null;
    }       

    try
    {
        SimpleDateFormat srcFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            
        Date date = srcFormatter.parse(dateStr);        

        SimpleDateFormat destFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");    
        returnDate = destFormatter.parse(destFormatter.format(date));           
    }
    catch (ParseException e)
    {
        dbacc.logError("Error while parsing date string" + e.getMessage());
    }       

    Calendar cal = Calendar.getInstance();
    cal.setTime(returnDate);

    return cal;
}

Binding for datetime types defined as follows...

<jxb:javaType name="java.util.Calendar" xmlType="xsd:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime"/>

Not sure what's wrong with the code. Any help is much appreciated.

Was it helpful?

Solution

Default Behaviour

When marshalling a java.util.Date a JAXB implementation will marshal them if they are not 0.

Java Model (Root)

import java.util.Date;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlType(propOrder = { "foo", "bar" })
public class Root {

    private Date foo;
    private Date bar;

    public Date getFoo() {
        return foo;
    }

    public void setFoo(Date foo) {
        this.foo = foo;
    }

    public Date getBar() {
        return bar;
    }

    public void setBar(Date bar) {
        this.bar = bar;
    }

}

Demo

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.setFoo(DatatypeConverter.parseDateTime("2013-08-02T11:50:00-04:00").getTime());
        root.setBar(DatatypeConverter.parseDateTime("2013-08-02T11:50:00.123-04:00").getTime());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <foo>2013-08-02T11:50:00-04:00</foo>
    <bar>2013-08-02T11:50:00.123-04:00</bar>
</root>

Forcing Milliseconds to Be Marshalled with an XmlAdapter

You could create an XmlAdapter to control the way the java.util.Date is marshalled out:

Leveraging an XmlAdapter when Starting from an XML Schema

Below is a link to an answer I gave demonstrating how to leverage an XmlAdapter when you generate your model from an XML Schema.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top