lucee.commons.i18n.FormatUtil.java Source code

Java tutorial

Introduction

Here is the source code for lucee.commons.i18n.FormatUtil.java

Source

/**
 *
 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either 
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 **/
package lucee.commons.i18n;

import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import lucee.commons.date.TimeZoneConstants;
import lucee.commons.io.IOUtil;
import lucee.commons.io.res.Resource;
import lucee.commons.lang.StringUtil;
import lucee.runtime.config.Config;
import lucee.runtime.engine.ThreadLocalPageContext;

import org.apache.commons.collections.map.ReferenceMap;

public class FormatUtil {

    public static final short FORMAT_TYPE_DATE = 1;
    public static final short FORMAT_TYPE_TIME = 2;
    public static final short FORMAT_TYPE_DATE_TIME = 3;
    public static final short FORMAT_TYPE_DATE_ALL = 4;

    private final static Map<String, DateFormat[]> formats = new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.SOFT);

    public static DateFormat[] getDateTimeFormats(Locale locale, TimeZone tz, boolean lenient) {

        String id = "dt-" + locale.hashCode() + "-" + tz.getID() + "-" + lenient;
        DateFormat[] df = formats.get(id);
        if (df == null) {
            List<DateFormat> list = new ArrayList<DateFormat>();
            list.add(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, locale));

            list.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.FULL, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, locale));

            list.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale));

            list.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.FULL, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale));
            list.add(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale));
            add24(list, locale);
            addCustom(list, locale, FORMAT_TYPE_DATE_TIME);
            df = list.toArray(new DateFormat[list.size()]);

            for (int i = 0; i < df.length; i++) {
                df[i].setLenient(lenient);
                df[i].setTimeZone(tz);
            }

            formats.put(id, df);
        }

        return df;
    }

    public static DateFormat[] getDateFormats(Locale locale, TimeZone tz, boolean lenient) {
        String id = "d-" + locale.hashCode() + "-" + tz.getID() + "-" + lenient;
        DateFormat[] df = formats.get(id);
        if (df == null) {
            List<DateFormat> list = new ArrayList<DateFormat>();
            list.add(DateFormat.getDateInstance(DateFormat.FULL, locale));
            list.add(DateFormat.getDateInstance(DateFormat.LONG, locale));
            list.add(DateFormat.getDateInstance(DateFormat.MEDIUM, locale));
            list.add(DateFormat.getDateInstance(DateFormat.SHORT, locale));
            addCustom(list, locale, FORMAT_TYPE_DATE);
            df = list.toArray(new DateFormat[list.size()]);

            for (int i = 0; i < df.length; i++) {
                df[i].setLenient(lenient);
                df[i].setTimeZone(tz);
            }
            formats.put(id, df);
        }
        return df;
    }

    public static DateFormat[] getTimeFormats(Locale locale, TimeZone tz, boolean lenient) {
        String id = "t-" + locale.hashCode() + "-" + tz.getID() + "-" + lenient;
        DateFormat[] df = formats.get(id);
        if (df == null) {
            List<DateFormat> list = new ArrayList<DateFormat>();
            list.add(DateFormat.getTimeInstance(DateFormat.FULL, locale));
            list.add(DateFormat.getTimeInstance(DateFormat.LONG, locale));
            list.add(DateFormat.getTimeInstance(DateFormat.MEDIUM, locale));
            list.add(DateFormat.getTimeInstance(DateFormat.SHORT, locale));
            add24(list, locale);
            addCustom(list, locale, FORMAT_TYPE_TIME);
            df = list.toArray(new DateFormat[list.size()]);

            for (int i = 0; i < df.length; i++) {
                df[i].setLenient(lenient);
                df[i].setTimeZone(tz);
            }
            formats.put(id, df);
        }
        return df;
    }

    private static void add24(List<DateFormat> list, Locale locale) {

        // if found h:mm:ss a add H:mm:ss ...
        String p;
        int index;
        SimpleDateFormat sdf;
        DateFormat[] df = list.toArray(new DateFormat[list.size()]);
        for (int i = 0; i < df.length; i++) {
            if (df[i] instanceof SimpleDateFormat) {
                p = ((SimpleDateFormat) df[i]).toPattern() + "";

                if (check(list, p, locale, "hh:mm:ss a", "HH:mm:ss"))
                    continue;
                if (check(list, p, locale, "h:mm:ss a", "H:mm:ss"))
                    continue;
                if (check(list, p, locale, "hh:mm a", "HH:mm"))
                    continue;
                if (check(list, p, locale, "h:mm a", "H:mm"))
                    continue;

                if (check(list, p, locale, "hh:mm:ssa", "HH:mm:ss"))
                    continue;
                if (check(list, p, locale, "h:mm:ssa", "H:mm:ss"))
                    continue;
                if (check(list, p, locale, "hh:mma", "HH:mm"))
                    continue;
                if (check(list, p, locale, "h:mma", "H:mm"))
                    continue;

                //if(check(list,p,locale,"HH:mm:ss","hh:mm:ss a")) continue;
                //if(check(list,p,locale,"H:mm:ss","h:mm:ss a")) continue;
                //if(check(list,p,locale,"HH:mm","hh:mm a")) continue;
                //if(check(list,p,locale,"H:mm","h:mm a")) continue;
            }
        }
    }

    private static boolean check(List<DateFormat> list, String p, Locale locale, String from, String to) {
        int index = p.indexOf(from);
        if (index != -1) {
            p = StringUtil.replace(p, from, to, true);
            SimpleDateFormat sdf = new SimpleDateFormat(p, locale);
            if (!list.contains(sdf))
                list.add(sdf);
            return true;
        }
        return false;
    }

    private static void addCustom(List<DateFormat> list, Locale locale, short formatType) {
        // get custom formats from file
        Config config = ThreadLocalPageContext.getConfig();
        Resource dir = config.getConfigDir().getRealResource("locales");
        if (dir.isDirectory()) {
            String appendix = "-datetime";
            if (formatType == FORMAT_TYPE_DATE)
                appendix = "-date";
            if (formatType == FORMAT_TYPE_TIME)
                appendix = "-time";

            Resource file = dir
                    .getRealResource(locale.getLanguage() + "-" + locale.getCountry() + appendix + ".df");
            if (file.isFile()) {
                try {
                    String content = IOUtil.toString(file, (Charset) null);
                    String[] arr = lucee.runtime.type.util.ListUtil.listToStringArray(content, '\n');
                    String line;
                    SimpleDateFormat sdf;
                    for (int i = 0; i < arr.length; i++) {
                        line = arr[i].trim();
                        if (StringUtil.isEmpty(line))
                            continue;
                        sdf = new SimpleDateFormat(line, locale);
                        if (!list.contains(sdf))
                            list.add(sdf);
                    }

                } catch (Throwable t) {
                }
            }
        }
    }

    /**
     * CFML Supported LS Formats
     * @param locale
     * @param tz
     * @param lenient
     * @return
     */
    public static DateFormat[] getCFMLFormats(TimeZone tz, boolean lenient) {
        String id = "cfml-" + Locale.ENGLISH.hashCode() + "-" + tz.getID() + "-" + lenient;
        DateFormat[] df = formats.get(id);
        if (df == null) {
            df = new SimpleDateFormat[] { new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM dd, yyyy HH:mm:ss a zzz", Locale.ENGLISH),
                    new SimpleDateFormat("MMM dd, yyyy HH:mm:ss a", Locale.ENGLISH),
                    new SimpleDateFormat("MMM dd, yyyy HH:mm:ss", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM d yyyy HH:mm:ssZ", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM d yyyy HH:mm:ss", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM d yyyy HH:mm", Locale.ENGLISH),
                    new SimpleDateFormat("EEE, MMM dd, yyyy HH:mm:ssZ", Locale.ENGLISH),
                    new SimpleDateFormat("EEE, MMM dd, yyyy HH:mm:ss", Locale.ENGLISH),
                    new SimpleDateFormat("EEEE, MMMM dd, yyyy H:mm:ss a zzz", Locale.ENGLISH),
                    new SimpleDateFormat("dd-MMM-yy HH:mm a", Locale.ENGLISH),
                    new SimpleDateFormat("dd-MMMM-yy HH:mm a", Locale.ENGLISH),
                    new SimpleDateFormat("EE, dd-MMM-yyyy HH:mm:ss zz", Locale.ENGLISH),
                    new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss zz", Locale.ENGLISH),
                    new SimpleDateFormat("EEE d, MMM yyyy HH:mm:ss zz", Locale.ENGLISH),
                    new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM, dd yyyy HH:mm:ssZ", Locale.ENGLISH),
                    new SimpleDateFormat("MMMM, dd yyyy HH:mm:ss", Locale.ENGLISH),
                    new SimpleDateFormat("yyyy/MM/dd HH:mm:ss zz", Locale.ENGLISH),
                    new SimpleDateFormat("dd MMM yyyy HH:mm:ss zz", Locale.ENGLISH),
                    new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'ZZ (z)", Locale.ENGLISH),
                    new SimpleDateFormat("dd MMM, yyyy HH:mm:ss", Locale.ENGLISH)
                    //,new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",Locale.ENGLISH)
            };

            for (int i = 0; i < df.length; i++) {
                df[i].setLenient(lenient);
                df[i].setTimeZone(tz);
            }
            formats.put(id, df);
        }
        return df;
    }

    public static DateFormat[] getFormats(Locale locale, TimeZone tz, boolean lenient, short formatType) {
        if (FORMAT_TYPE_DATE_TIME == formatType)
            return getDateTimeFormats(locale, TimeZoneConstants.GMT, true);
        if (FORMAT_TYPE_DATE == formatType)
            return getDateFormats(locale, TimeZoneConstants.GMT, true);
        if (FORMAT_TYPE_TIME == formatType)
            return getTimeFormats(locale, TimeZoneConstants.GMT, true);

        DateFormat[] dt = getDateTimeFormats(locale, TimeZoneConstants.GMT, true);
        DateFormat[] d = getDateFormats(locale, TimeZoneConstants.GMT, true);
        DateFormat[] t = getTimeFormats(locale, TimeZoneConstants.GMT, true);

        DateFormat[] all = new DateFormat[dt.length + d.length + t.length];
        for (int i = 0; i < dt.length; i++) {
            all[i] = dt[i];
        }
        for (int i = 0; i < d.length; i++) {
            all[i + dt.length] = d[i];
        }
        for (int i = 0; i < t.length; i++) {
            all[i + dt.length + d.length] = t[i];
        }
        return getDateTimeFormats(locale, TimeZoneConstants.GMT, true);
    }

    public static String[] getSupportedPatterns(Locale locale, short formatType) {
        DateFormat[] _formats = getFormats(locale, TimeZoneConstants.GMT, true, formatType);
        String[] patterns = new String[_formats.length];
        for (int i = 0; i < _formats.length; i++) {
            if (!(_formats[i] instanceof SimpleDateFormat))
                return null; // all or nothing
            patterns[i] = ((SimpleDateFormat) _formats[i]).toPattern();
        }

        return patterns;
    }

}