Search code examples
javaxmlsimple-framework

Does Simple XML support xsd:dateTime date format out of box?


Does Simple XML support any Date formats other than the format 2007-01-03 18:05:11.234 GMT mentioned in the tutorial? If not, should I implement a custom Transformer, or is there an easier solution?

I created a test case for xsd:dateTime parsing which fails at the moment:

import org.junit.Test;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import static org.junit.Assert.assertEquals;

public class XsdDateTimeSimpleXmlTest {

    String DUMMY_XML = "<dummy><date>2011-12-01T11:46:52</date></dummy>";

    @Test
    public void testDateTimeDeserialization() throws Exception {
        Dummy expected = new Dummy(expectedDate());
        Dummy actual = deserialize(DUMMY_XML);
        assertEquals(expected, actual);
    }

    Date expectedDate() {
        Calendar c = Calendar.getInstance();
        c.set(2011, 12-1, 1, 11, 46, 52);
        c.set(Calendar.MILLISECOND, 0);
        c.setTimeZone(TimeZone.getTimeZone("UTC"));
        return c.getTime();
    }

    Dummy deserialize(String xml) throws Exception {
        Deserializer<Dummy> des = new Deserializer<Dummy>(Dummy.class);
        return des.read(xml);
    }

    @Root
    static class Dummy {

        @Element
        Date date;

        Dummy() { }

        Dummy(Date date) {
            this.date = date;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Dummy dummy = (Dummy) o;
            if (!date.equals(dummy.date)) return false;
            return true;
        }

        @Override
        public int hashCode() {
            return date.hashCode();
        }

        @Override
        public String toString() {
            return "Dummy{" +
                    "date=" + date +
                    '}';
        }
    }

}

I get java.text.ParseException: Unparseable date: "2011-12-01T11:46:52".


Solution

  • If you want to use any other format except of those which are not supported by SimpleXML, then you need to do little work around for this, You have to write your custom Transform which will handle other other formats and that is not a great deal to do it, really it's so simple.

    Put attribute annotation on your date field like this

    @Attribute(name="date", required=true) 
    private Date date;
    

    CustomDateFormatTransformer

    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.simpleframework.xml.transform.Transform;
    
    public class CustomDateFormatTransformer implements Transform<Date> {
    
    private DateFormat df;
    public DateFormatTransformer(DateFormat df) {
        this.df= df;
    }
    
    @Override
    public Date read(String value) throws Exception {
        return df.parse(value);
    }
    @Override
    public String write(Date value) throws Exception {
        return df.format(value);
    }
    }
    

    All things are ready, finally you can call it form you client code as following

        DateFormat dateFormat = new SimpleDateFormat("Your_date_format_here");
        RegistryMatcher registryMatcher = new RegistryMatcher();
        registryMatcher .bind(Date.class, new DateFormatTransformer(dateFormat));
    
    // serialize or Deserializer it here .....
    

    Here are the some formats which are only supported by SimpleXML

     yyyy-MM-dd HH:mm:ss.S z,  yyyy-MM-dd HH:mm:ss z
       yyyy-MM-dd z,   yyyy-MM-dd