Format Date Fields to String in XStream
Asked Answered
K

3

6

I have a date field, which when converted to xml using XStream, gives time in milliseconds and zone. I just need to convert or format it as "MMMM dd, yyyy HH:mm:ss". How to do that using XStream? I don't want to change the getters and setters. Thanks.

My class:

    public class Datas {
    private String name;
    private Calendar dob;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Calendar getDob() {
        return dob;
    }

    public void setDob(Calendar dob) {
        this.dob = dob;
    }

    public static void main(String[] args) {
        Datas datas = new Datas();
        datas.setName("Ahamed");
        datas.setDob(Calendar.getInstance());
        XStream stream = new XStream();
        System.out.println(stream.toXML(datas));
    }
}

Output:

<Datas>
  <name>Ahamed</name>
  <dob>
    <time>1329081818801</time>
    <timezone>Asia/Calcutta</timezone>
  </dob>
</Datas>

I would like to format the dob tag without changing the getters and setters. Thanks.

Kabyle answered 12/2, 2012 at 21:16 Comment(2)
Huge XML as in? Can we have an example?Slily
Check out the XStream - Converter Tutorial. There's a section regarding date conversion.Anglofrench
K
5

Custom converter for Calendar fields:

public class DateConverter implements Converter {

    private SimpleDateFormat formatter = new SimpleDateFormat(
            "MMMM dd, yyyy HH:mm:ss");

    public boolean canConvert(Class clazz) {
        // This converter is only for Calendar fields.
        return Calendar.class.isAssignableFrom(clazz);
    }

    public void marshal(Object value, HierarchicalStreamWriter writer,
            MarshallingContext context) {
        Calendar calendar = (Calendar) value;
        Date date = calendar.getTime();
        writer.setValue(formatter.format(date));
    }

    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext context) {
        GregorianCalendar calendar = new GregorianCalendar();
        try {
            calendar.setTime(formatter.parse(reader.getValue()));
        } catch (ParseException e) {
            throw new ConversionException(e.getMessage(), e);
        }
        return calendar;
    }
}

Register the above converter to XStream object as follows:

XStream xStream = new XStream();
xStream.registerConverter(new DateConverter());

Now xStream object will look for Calendar fields and will marshall as defined in Custom Converter.

Kabyle answered 13/2, 2012 at 8:4 Comment(1)
Be carefull with this: SimpleDateFormat is not thread-safe. The easiest way to solve this is to construct a new SDF each time it is needed.Fidelafidelas
C
12

An easy way is to register an (XStream!) DateConverter with the appropriate formats, e.g.:

import com.thoughtworks.xstream.converters.basic.DateConverter;

XStream xstream = new XStream();
String dateFormat = "yyyyMMdd";
String timeFormat = "HHmmss";
String[] acceptableFormats = {timeFormat};
xstream.registerConverter(new DateConverter(dateFormat, acceptableFormats));

This works for me and I didn't need to create a new converter class.

Contraceptive answered 4/9, 2013 at 10:23 Comment(0)
K
5

Custom converter for Calendar fields:

public class DateConverter implements Converter {

    private SimpleDateFormat formatter = new SimpleDateFormat(
            "MMMM dd, yyyy HH:mm:ss");

    public boolean canConvert(Class clazz) {
        // This converter is only for Calendar fields.
        return Calendar.class.isAssignableFrom(clazz);
    }

    public void marshal(Object value, HierarchicalStreamWriter writer,
            MarshallingContext context) {
        Calendar calendar = (Calendar) value;
        Date date = calendar.getTime();
        writer.setValue(formatter.format(date));
    }

    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext context) {
        GregorianCalendar calendar = new GregorianCalendar();
        try {
            calendar.setTime(formatter.parse(reader.getValue()));
        } catch (ParseException e) {
            throw new ConversionException(e.getMessage(), e);
        }
        return calendar;
    }
}

Register the above converter to XStream object as follows:

XStream xStream = new XStream();
xStream.registerConverter(new DateConverter());

Now xStream object will look for Calendar fields and will marshall as defined in Custom Converter.

Kabyle answered 13/2, 2012 at 8:4 Comment(1)
Be carefull with this: SimpleDateFormat is not thread-safe. The easiest way to solve this is to construct a new SDF each time it is needed.Fidelafidelas
W
0

You have to use a custom converter in which under the marshal method modify your date format as you wish.
It should be done after DOB node.
I don't think you need to do anything in unmarshal method.
Good Luck :)

Waterscape answered 13/2, 2012 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.