Over a million developers have joined DZone.

JAXB and Joda-Time: Dates and Times

· Java Zone

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

Joda-Time provides an alternative to the Date and Calendar classes currently provided in Java SE.  Since they are provided in a separate library JAXB does not provide a default mapping for these classes.  We can supply the necessary mapping via XmlAdapters.  In this post we will cover the following Joda-Time types:  DateTime, DateMidnight, LocalDate, LocalTime, LocalDateTime.



Java Model

The following domain model will be used for this example:


package blog.jodatime;
 
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
 
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
 
@XmlRootElement
@XmlType(propOrder={
    "dateTime",
    "dateMidnight",
    "localDate",
    "localTime",
    "localDateTime"})
public class Root {
 
    private DateTime dateTime;
    private DateMidnight dateMidnight;
    private LocalDate localDate;
    private LocalTime localTime;
    private LocalDateTime localDateTime;
 
    public DateTime getDateTime() {
        return dateTime;
    }
 
    public void setDateTime(DateTime dateTime) {
        this.dateTime = dateTime;
    }
 
    public DateMidnight getDateMidnight() {
        return dateMidnight;
    }
 
    public void setDateMidnight(DateMidnight dateMidnight) {
        this.dateMidnight = dateMidnight;
    }
 
    public LocalDate getLocalDate() {
        return localDate;
    }
 
    public void setLocalDate(LocalDate localDate) {
        this.localDate = localDate;
    }
 
    public LocalTime getLocalTime() {
        return localTime;
    }
 
    public void setLocalTime(LocalTime localTime) {
        this.localTime = localTime;
    }
 
    public LocalDateTime getLocalDateTime() {
        return localDateTime;
    }
 
    public void setLocalDateTime(LocalDateTime localDateTime) {
        this.localDateTime = localDateTime;
    }
 
}
XmlAdapters

Since Joda-Time and XML Schema both represent data and time information according to ISO 8601 the implementation of the XmlAdapters is quite trivial.

DateTimeAdapter
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateTime;
 
public class DateTimeAdapter
    extends XmlAdapter<String, DateTime>{
 
    public DateTime unmarshal(String v) throws Exception {
        return new DateTime(v);
    }
 
    public String marshal(DateTime v) throws Exception {
        return v.toString();
    }
 
}


DateMidnightAdapter
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateMidnight;
 
public class DateMidnightAdapter
    extends XmlAdapter<String, DateMidnight> {
 
    public DateMidnight unmarshal(String v) throws Exception {
        return new DateMidnight(v);
    }
 
    public String marshal(DateMidnight v) throws Exception {
        return v.toString();
    }
 
}


LocalDateAdapter
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDate;
 
public class LocalDateAdapter
    extends XmlAdapter<String, LocalDate>{
 
    public LocalDate unmarshal(String v) throws Exception {
        return new LocalDate(v);
    }
 
    public String marshal(LocalDate v) throws Exception {
        return v.toString();
    }
 
}


LocalTimeAdapter
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalTime;
 
public class LocalTimeAdapter
    extends XmlAdapter<String, LocalTime> {
 
    public LocalTime unmarshal(String v) throws Exception {
        return new LocalTime(v);
    }
 
    public String marshal(LocalTime v) throws Exception {
        return v.toString();
    }
 
}


LocalDateTimeAdapter
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDateTime;
 
public class LocalDateTimeAdapter
    extends XmlAdapter<String, LocalDateTime>{
 
    public LocalDateTime unmarshal(String v) throws Exception {
        return new LocalDateTime(v);
    }
 
    public String marshal(LocalDateTime v) throws Exception {
        return v.toString();
    }
 
}


Registering the XmlAdapters

We will use the @XmlJavaTypeAdapters annotation to register the Joda-Time types at the package level.  This means that whenever these types are found on a field/property on a class within this package the XmlAdapter will automatically be applied.
@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(type=DateTime.class,
        value=DateTimeAdapter.class),
    @XmlJavaTypeAdapter(type=DateMidnight.class,
        value=DateMidnightAdapter.class),
    @XmlJavaTypeAdapter(type=LocalDate.class,
        value=LocalDateAdapter.class),
    @XmlJavaTypeAdapter(type=LocalTime.class,
        value=LocalTimeAdapter.class),
    @XmlJavaTypeAdapter(type=LocalDateTime.class,
        value=LocalDateTimeAdapter.class)
})
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
 
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;


Demo

To run the following demo you will need the Joda-Time jar on your classpath.  It can be obtained here:
  • http://sourceforge.net/projects/joda-time/files/joda-time/
    package blog.jodatime;
     
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
     
    import org.joda.time.DateMidnight;
    import org.joda.time.DateTime;
    import org.joda.time.LocalDate;
    import org.joda.time.LocalDateTime;
    import org.joda.time.LocalTime;
     
    public class Demo {
     
        public static void main(String[] args) throws Exception {
            Root root = new Root();
            root.setDateTime(new DateTime(2011, 5, 30, 11, 2, 30, 0));
            root.setDateMidnight(new DateMidnight(2011, 5, 30));
            root.setLocalDate(new LocalDate(2011, 5, 30));
            root.setLocalTime(new LocalTime(11, 2, 30));
            root.setLocalDateTime(new LocalDateTime(2011, 5, 30, 11, 2, 30));
     
            JAXBContext jc = JAXBContext.newInstance(Root.class);
     
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(root, System.out);
        }
     
    }


Output

The following is the output from our demo code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <dateTime>2011-05-30T11:02:30.000-04:00</dateTime>
    <dateMidnight>2011-05-30T00:00:00.000-04:00</dateMidnight>
    <localDate>2011-05-30</localDate>
    <localTime>11:02:30.000</localTime>
    <localDateTime>2011-05-30T11:02:30.000</localDateTime>
</root>

 

From http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}