2

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.

Cootri
  • 3,806
  • 20
  • 30
Kiran
  • 53
  • 2
  • 8

1 Answers1

3

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.

Community
  • 1
  • 1
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    I actually figured that marshalling is only done when milliseconds are not 0 by hardcoding a timestamp with non-zero ms value. Your answer, however, provides more details about how we can actually force it to add ms regardless. Thanks for the explanation and examples. That definitely helps. – Kiran Aug 02 '13 at 17:11