You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Here is an ObjectStringConverter implementation that will convert java.util.Date into the ISO 8601 format used in the XML Schema Definition types xsd:dateTime, xsd:date, and xsd:time, depending on the specified flavour.

import java.text.*;
import java.util.*;
import org.apache.commons.betwixt.expression.*;
import org.apache.commons.betwixt.strategy.*;

/**
 * @author Jesse Sweetland
 */
public class DateObjectStringConverter extends ObjectStringConverter {
    private static final DateFormat PSUEDO_ISO8601_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    private static final DateFormat PSUEDO_ISO8601_DATETIME_FORMAT_TZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    private static final DateFormat PSUEDO_ISO8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    private static final DateFormat PSUEDO_ISO8601_DATE_FORMAT_TZ = new SimpleDateFormat("yyyy-MM-ddZ");
    private static final DateFormat PSUEDO_ISO8601_TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
    private static final DateFormat PSUEDO_ISO8601_TIME_FORMAT_TZ = new SimpleDateFormat("HH:mm:ssZ");
    
    protected String getFlavor(Context context) {
        return context.getOptions().getValue(FLAVOUR_OPTION_NAME);
    }
    
    public String objectToString(Object object, Class type, Context context) {
        String flavor = getFlavor(context);
        if("xsd:date".equals(flavor)){
            return toIso8601Date((Date)object);
        } else if("xsd:time".equals(flavor)){
            return toIso8601Time((Date)object);
        } else {
            // Assume xsd:dateTime if not specified
            return toIso8601DateTime((Date)object);
        }
    }
    
    public Object stringToObject(String value, Class type, Context context) {
        String flavor = getFlavor(context);
        if("xsd:date".equals(flavor)){
            return fromIso8601Date(value);
        } else if("xsd:time".equals(flavor)){
            return fromIso8601Time(value);
        } else {
            // Assume xsd:dateTime if not specified
            return fromIso8601DateTime(value);
        }
    }

    private String toIso8601DateTime(Date dateTime) {
        if(dateTime == null) return null;
        StringBuilder psuedoIso8601DateTime = new StringBuilder(PSUEDO_ISO8601_DATETIME_FORMAT_TZ.format(dateTime));
        String iso8601DateTime = psuedoIso8601DateTime.insert(psuedoIso8601DateTime.length() - 2, ':').toString();
        return iso8601DateTime;
    }
    
    private String toIso8601Date(Date date) {
        if(date == null) return null;
        StringBuilder psuedoIso8601Date = new StringBuilder(PSUEDO_ISO8601_DATE_FORMAT_TZ.format(date));
        String iso8601Date = psuedoIso8601Date.insert(psuedoIso8601Date.length() - 2, ':').toString();
        return iso8601Date;
    }
 
    private String toIso8601Time(Date time) {
        if(time == null) return null;
        StringBuilder psuedoIso8601Time = new StringBuilder(PSUEDO_ISO8601_TIME_FORMAT_TZ.format(time));
        String iso8601Time = psuedoIso8601Time.insert(psuedoIso8601Time.length() - 2, ':').toString();
        return iso8601Time;
    }
    
    private Date fromIso8601DateTime(String iso8601DateTime) {
        if(iso8601DateTime == null) return null;
        try {
            iso8601DateTime = iso8601DateTime.trim();
            boolean tzPresent = iso8601DateTime.length() > 19;
            if(tzPresent) {
                String psuedoIso8601DateTime;
                if(iso8601DateTime.charAt(19) == 'Z') {
                    psuedoIso8601DateTime = new StringBuilder(iso8601DateTime.substring(0, 19)).append("-0000").toString();
                } else {
                    psuedoIso8601DateTime = new StringBuilder(iso8601DateTime).deleteCharAt(22).toString();
                }
                return PSUEDO_ISO8601_DATETIME_FORMAT_TZ.parse(psuedoIso8601DateTime);
            } else {
                return PSUEDO_ISO8601_DATETIME_FORMAT.parse(iso8601DateTime);
            }
        } catch(Throwable t) {
            throw new IllegalArgumentException(t);
        }
    }
    
    private Date fromIso8601Date(String iso8601Date) {
        if(iso8601Date == null) return null;
        try {
            iso8601Date = iso8601Date.trim();
            boolean tzPresent = iso8601Date.length() > 10;
            if(tzPresent) {
                String psuedoIso8601Date;
                if(iso8601Date.charAt(10) == 'Z') {
                    psuedoIso8601Date = new StringBuilder(iso8601Date.substring(0, 10)).append("-0000").toString();
                } else {
                    psuedoIso8601Date = new StringBuilder(iso8601Date).deleteCharAt(13).toString();
                }
                return PSUEDO_ISO8601_DATE_FORMAT_TZ.parse(psuedoIso8601Date);
            } else {
                return PSUEDO_ISO8601_DATE_FORMAT.parse(iso8601Date);
            }
        } catch(Throwable t) {
            throw new IllegalArgumentException(t);
        }
    }
 
    private Date fromIso8601Time(String iso8601Time) {
        if(iso8601Time == null) return null;
        try {
            iso8601Time = iso8601Time.trim();
            boolean tzPresent = iso8601Time.length() > 8;
            if(tzPresent) {
                String psuedoIso8601Time;
                if(iso8601Time.charAt(8) == 'Z') {
                    psuedoIso8601Time = new StringBuilder(iso8601Time.substring(0, 8)).append("-0000").toString();
                } else {
                    psuedoIso8601Time = new StringBuilder(iso8601Time).deleteCharAt(11).toString();
                }
                return PSUEDO_ISO8601_TIME_FORMAT_TZ.parse(psuedoIso8601Time);
            } else {
                return PSUEDO_ISO8601_TIME_FORMAT.parse(iso8601Time);
            }
        } catch(Throwable t) {
            throw new IllegalArgumentException(t);
        }
    }
    
    public static void main(String[] args) {
        DateObjectStringConverter dosc = new DateObjectStringConverter();
        
        Date now = new Date();
        
        System.out.println(now + " => " + dosc.toIso8601DateTime(now));
        System.out.println(now + " => " + dosc.toIso8601Date(now));
        System.out.println(now + " => " + dosc.toIso8601Time(now));
        
        String dateTime = "2006-08-09T13:26:50";
        System.out.println(dateTime + " => " + dosc.fromIso8601DateTime(dateTime));
        
        String dateTimeTz = "2006-08-09T13:26:50-05:00";
        System.out.println(dateTimeTz + " => " + dosc.fromIso8601DateTime(dateTimeTz));
        
        String dateTimeUtc = "2006-08-09T13:26:50Z";
        System.out.println(dateTimeUtc + " => " + dosc.fromIso8601DateTime(dateTimeUtc));
        
        String date = "2006-08-09";
        System.out.println(date + " => " + dosc.fromIso8601Date(date));
        
        String dateTz = "2006-08-09-05:00";
        System.out.println(date + " => " + dosc.fromIso8601Date(dateTz));
        
        String dateUtc = "2006-08-09Z";
        System.out.println(date + " => " + dosc.fromIso8601Date(dateUtc));
        
        String time = "13:26:50";
        System.out.println(time + " => " + dosc.fromIso8601Time(time));
        
        String timeTz = "13:26:50-05:00";
        System.out.println(timeTz + " => " + dosc.fromIso8601Time(timeTz));
        
        String timeUtc = "13:26:50Z";
        System.out.println(timeUtc + " => " + dosc.fromIso8601Time(timeUtc));
    }
}

The .betwixt mapping documents will look something like this:

<?xml version="1.0"?>
<info>
    <element name="myElement">
        <element name="dateTime" property="dateTime">
            <option>
                <name>org.apache.commons.betwixt.flavour</name>
                <value>xsd:dateTime</value>
            </option>
        </element>
        <element name="date" property="date">
            <option>
                <name>org.apache.commons.betwixt.flavour</name>
                <value>xsd:date</value>
            </option>
        </element>
        <element name="time" property="time">
            <option>
                <name>org.apache.commons.betwixt.flavour</name>
                <value>xsd:time</value>
            </option>
        </element>
    </element>
</info>

Note that if no flavor is specified, it defaults to dateTime format. Also, when writing dates, the timezone is always specified (which is highly recommended).

  • No labels