All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jidefx.utils.converter.AbstractDateConverter Maven / Gradle / Ivy

The newest version!
/*
 * @(#)DateConverter.java 5/19/2013
 *
 * Copyright 2002 - 2013 JIDE Software Inc. All rights reserved.
 */

package jidefx.utils.converter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * {@link jidefx.utils.converter.ObjectConverter} implementation for {@link java.util.Date}, {@link java.util.Calendar}
 * or {@link Number}. All of aforementioned data types can be accepted by the toString method. For the fromString
 * method, it will only return {@link java.util.Date}. Its subclasses might return Calendar or Number.
 */
abstract public class AbstractDateConverter extends DefaultObjectConverter {

    /**
     * A converter context to tell the DateConverter using a DateFormat from SimpleDateFormat.getDateTimeInstance to do
     * the conversion.
     */
    public static final ConverterContext CONTEXT_DATETIME = new ConverterContext("DateTime"); //NON-NLS
    /**
     * A converter context to tell the DateConverter using a DateFormat from SimpleDateFormat.getTimeInstance to do the
     * conversion.
     */
    public static final ConverterContext CONTEXT_TIME = new ConverterContext("Time"); //NON-NLS
    /**
     * A converter context to tell the DateConverter using a DateFormat from SimpleDateFormat.getDateInstance to do the
     * conversion. It is the same as using CONTEXT_DEFAULT.
     */
    public static final ConverterContext CONTEXT_DATE = new ConverterContext("");

    /**
     * A property for the converter context. You can set a {@link java.text.DateFormat} to it and the converter will use
     * it to do the conversion.
     */
    public static final String PROPERTY_DATE_FORMAT = "DateFormat"; //NON-NLS

    private DateFormat _shortFormat = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
    private DateFormat _mediumFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
    private DateFormat _longFormat = SimpleDateFormat.getDateInstance(DateFormat.LONG);

    private DateFormat _defaultFormat = SimpleDateFormat.getDateInstance(DateFormat.DEFAULT);

    private DateFormat _shortDateTimeFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
    private DateFormat _mediumDateTimeFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
    private DateFormat _longDateTimeFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);

    private DateFormat _defaultDateTimeFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);

    private DateFormat _shortTimeFormat = SimpleDateFormat.getTimeInstance(DateFormat.SHORT);
    private DateFormat _mediumTimeFormat = SimpleDateFormat.getTimeInstance(DateFormat.MEDIUM);
    private DateFormat _longTimeFormat = SimpleDateFormat.getTimeInstance(DateFormat.LONG);

    private DateFormat _defaultTimeFormat = SimpleDateFormat.getTimeInstance(DateFormat.DEFAULT);


    /**
     * Creates a DateConverter.
     */
    public AbstractDateConverter() {
    }

    /**
     * Converts the object to String. The object can be a Calendar, a Date or a Number. As long as the DateFormat can
     * format it correctly, it will be converted to a String. If the object is already a String, we will return it
     * directly as it is.
     *
     * @param object  the object to be converted
     * @param context the converter context.
     * @return the string
     */
    synchronized public String anyDateToString(Object object, ConverterContext context) {
        if (object == null) {
            return "";
        }

        TimeZone timeZone;
        if (object instanceof Calendar) {
            timeZone = ((Calendar) object).getTimeZone();
            object = ((Calendar) object).getTime();
        }
        else if (object instanceof Date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(((Date) object));
            timeZone = cal.getTimeZone();
        }
        else {
            timeZone = TimeZone.getDefault();
        }

        if (object instanceof Date || object instanceof Number) {
            Object format = context != null ? context.getProperties().get(PROPERTY_DATE_FORMAT) : null;
            if (format instanceof DateFormat) {
                return ((DateFormat) format).format(object);
            }
            else if (CONTEXT_DATETIME.equals(context)) {
                _defaultDateTimeFormat.setTimeZone(timeZone);
                return _defaultDateTimeFormat.format(object);
            }
            else if (CONTEXT_TIME.equals(context)) {
                _defaultTimeFormat.setTimeZone(timeZone);
                return _defaultTimeFormat.format(object);
            }
            else /* if (CONTEXT_DATE.equals(context)) */ {
                _defaultFormat.setTimeZone(timeZone);
                return _defaultFormat.format(object);
            }
        }
        else if (object instanceof String) {
            return (String) object;
        }
        else {
            return null;
        }
    }

    /**
     * Converts from a String to a Date. It will use the DateFormat defined as {@link #PROPERTY_DATE_FORMAT} if any.
     * Otherwise it will try different default DateFormat according to the context (Date, Time or DateTime). At last it
     * will try the following commonly used format patterns in order of "M/d/yyyy", "MM/dd/yyyy", "yyyy-MM-dd",
     * "yy-MM-dd", "yyyyMMdd", "yyMMdd", "dd-MMM-yy", "dd-MMM-yyyy", until it finds a match. We do that so that users
     * could type in other date formats and still could be recognized.
     *
     * @param string  the string to be converted.
     * @param context the context.
     * @return the Date. If the string is null or empty, null will be returned. If the string cannot be parsed as a
     *         date, the string itself will be returned.
     */
    synchronized public Object fromStringToDate(String string, ConverterContext context) {
        if (string == null) {
            return null;
        }

        string = string.trim();
        if (string.length() == 0) {
            return null;
        }

        try {
            Object format = context != null ? context.getProperties().get(PROPERTY_DATE_FORMAT) : null;
            if (format instanceof DateFormat) {
                try {
                    return ((DateFormat) format).parse(string);
                }
                catch (ParseException e) {
                    // ignore
                }
            }

            if (CONTEXT_DATETIME.equals(context)) {
                return _defaultDateTimeFormat.parse(string);
            }
            else if (CONTEXT_TIME.equals(context)) {
                return _defaultTimeFormat.parse(string);
            }
            else /* if (CONTEXT_DATE.equals(context)) */ {
                return _defaultFormat.parse(string);
            }
        }
        catch (ParseException e1) { // if current formatter doesn't work try those default ones.
            if (CONTEXT_DATETIME.equals(context)) {
                try {
                    return _shortDateTimeFormat.parse(string);
                }
                catch (ParseException e2) {
                    try {
                        return _mediumDateTimeFormat.parse(string);
                    }
                    catch (ParseException e3) {
                        try {
                            return _longDateTimeFormat.parse(string);
                        }
                        catch (ParseException e4) {
                            // null
                        }
                    }
                }
            }
            else if (CONTEXT_TIME.equals(context)) {
                try {
                    return _shortTimeFormat.parse(string);
                }
                catch (ParseException e2) {
                    try {
                        return _mediumTimeFormat.parse(string);
                    }
                    catch (ParseException e3) {
                        try {
                            return _longTimeFormat.parse(string);
                        }
                        catch (ParseException e4) {
                            return string;  // nothing works just return null so that old value will be kept.
                        }
                    }
                }
            }
            else /* if (CONTEXT_DATE.equals(context)) */ {
                try {
                    return _shortFormat.parse(string);
                }
                catch (ParseException e2) {
                    try {
                        return _mediumFormat.parse(string);
                    }
                    catch (ParseException e3) {
                        try {
                            return _longFormat.parse(string);
                        }
                        catch (ParseException e4) {
                            // null
                        }
                    }
                }
            }
        }

        // try other default formats
        String[] formatStrings = {"M/d/yyyy", "MM/dd/yyyy", "yyyy-MM-dd", "yy-MM-dd", "yyyyMMdd", "yyMMdd", "dd-MMM-yy", "dd-MMM-yyyy"}; //NON-NLS
        SimpleDateFormat sdf;
        for (String formatString : formatStrings) {
            try {
                sdf = new SimpleDateFormat(formatString);
                return sdf.parse(string);
            }
            catch (ParseException ex) {
                // break;
            }
        }
        return null;  // nothing works just return null so that old value will be kept.
    }

    /**
     * Gets the default format for date. This is used only when context is {@link #CONTEXT_DATE}.
     *
     * @return the default format for date.
     */
    public DateFormat getDefaultDateFormat() {
        return _defaultFormat;
    }

    /**
     * Sets the default format to format date. This is used only when context is {@link #CONTEXT_DATE}.
     *
     * @param defaultDateFormat the new default format for date.
     */
    public void setDefaultDateFormat(DateFormat defaultDateFormat) {
        _defaultFormat = defaultDateFormat;
    }

    /**
     * Gets the default format for time. This is used only when context is {@link #CONTEXT_TIME}.
     *
     * @return the default format for time.
     */
    public DateFormat getDefaultTimeFormat() {
        return _defaultTimeFormat;
    }

    /**
     * Sets the default format to format time. This is used only when context is {@link #CONTEXT_TIME}.
     *
     * @param defaultTimeFormat the new default format for time.
     */
    public void setDefaultTimeFormat(DateFormat defaultTimeFormat) {
        _defaultTimeFormat = defaultTimeFormat;
    }

    /**
     * Gets the default format for date/time. This is used only when context is {@link #CONTEXT_DATETIME}.
     *
     * @return the default format for date/time.
     */
    public DateFormat getDefaultDateTimeFormat() {
        return _defaultDateTimeFormat;
    }

    /**
     * Sets the default format to format date/time. This is used only when context is {@link #CONTEXT_DATETIME}.
     *
     * @param defaultDateTimeFormat the new default format for date/time.
     */
    public void setDefaultDateTimeFormat(DateFormat defaultDateTimeFormat) {
        _defaultDateTimeFormat = defaultDateTimeFormat;
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy