Java 自动识别日期格式

/ Java / 没有评论 / 4544浏览

原理

  1. 通过将不全的格式替换为全格式 yyyy-MM-dd HH🇲🇲ss.SSS
  2. 遍历所有格式进行替换,假如替换成功,则根据标记位表示是否终止,标记不终止是为了识别英文时间。
  3. 将全格式 yyyy-MM-dd HH🇲🇲ss.SSS 转换为时间对象.
  4. 由于编辑器原因,可能字符有错。具体代码请查看文件 DateUtils.java,可以右击另存为。

识别格式

package com.yanzuoguang.light.Utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 将时间格式字符串转换为时间
 * Created by 颜佐光 on 2018/6/8.
 */
public class DateUtils {

    /**
     * 无符号正则表达式
     */
    public static final String DATE_FORMAT_NO_SPLIT_REGEX = "^(\\d{4})(\\d{2})(\\d{2})$";
    /**
     * 有符号正常日期格式
     */
    public static final String DATE_FORMAT_COMMON_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2})$";
    /**
     * 有符号正常日期格式替换
     */
    public static final String DATE_FORMAT_COMMON_REPLACE = "$1-$2-$3 00:00:00.000";
    /**
     * 倒序的日期格式
     */
    public static final String DATE_FORMAT_REVERT_REGEX = "^(\\d{1,2})[/-](\\d{1,2})[/-](\\d{4,})$";
    /**
     * 有符号正常日期格式替换
     */
    public static final String DATE_FORMAT_REVERT_REPLACE = "$3-$2-$1 00:00:00.000";
    /**
     * 正常时间格式
     */
    public static final String DATETIME_HOUR_FORMAT_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2}).{1}(\\d{1,2}):(\\d{1,2})$";
    /**
     * 正常时间格式替换
     */
    public static final String DATETIME_HOUR_FORMAT_REPLACE =  "$1-$2-$3 $4:$5:00.000";
    /**
     * 正常时间格式
     */
    public static final String DATETIME_FORMAT_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2}).{1}(\\d{1,2}):(\\d{1,2}):(\\d{1,2})$";
    /**
     * 正常时间格式替换
     */
    public static final String DATETIME_FORMAT_REPLACE =  "$1-$2-$3 $4:$5:$6.000";
    /**
     * 时间格式化字符串 yyyy-MM-dd HH🇲🇲ss.SSS
     */
    public static final String DATETIME_FULL_FORMAT = "yyyy-MM-dd HH🇲🇲ss.SSS";

    /**
     * 缓存的自动识别的格式正则表达式
     */
    private static List<DateReplace> autoDateCache = new ArrayList<DateReplace>();

    static {
        registerAutoFormat(DATE_FORMAT_NO_SPLIT_REGEX, DATE_FORMAT_COMMON_REPLACE);
        registerAutoFormat(DATE_FORMAT_COMMON_REGEX, DATE_FORMAT_COMMON_REPLACE);
        registerAutoFormat(DATE_FORMAT_REVERT_REGEX, DATE_FORMAT_REVERT_REPLACE);
        registerAutoFormat(DATETIME_HOUR_FORMAT_REGEX, DATETIME_HOUR_FORMAT_REPLACE);
        registerAutoFormat(DATETIME_FORMAT_REGEX, DATETIME_FORMAT_REPLACE);
    }

    /**
     * 时间格式字符串
     */
    private static class DateReplace {
        // 正则表达式
        public String regex;
        // 替换表达式
        public String replace;
        // 终止标志位
        public boolean end;
    }

    /**
     * 注册正则表达式,将时间转换为正确格式的正则表达式,后注册的会优先执行 。
     *
     * @param regex   正则表达式
     * @param replace 替换表达式
     */
    public static void registerAutoFormat(String regex, String replace) {
        registerAutoFormat(regex, replace, true);
    }

    /**
     * 注册正则表达式,将时间转换为正确格式的正则表达式,后注册的会优先执行 。
     *
     * @param regex   正则表达式
     * @param replace 替换表达式
     * @param end     是否需要结束
     */
    public static void registerAutoFormat(String regex, String replace, boolean end) {
        DateReplace item = new DateReplace();
        item.regex = regex;
        item.replace = replace;
        item.end = end;
        autoDateCache.add(item);
    }

    /**
     * 根据时间字符串自动识别时间
     *
     * @param date 时间字符串
     * @return 时间
     */
    public static Date getAutoDate(String date) throws ParseException {
        if (date == null) {
            return null;
        }
        int size = autoDateCache.size();
        for (int i = size - 1; i >= 0; i--) {
            // 遍历所有时间格式
            DateReplace item = autoDateCache.get(i);
            String dateTo = date.replaceAll(item.regex, item.replace);
            // 如何替换成功,且终止标志位为true则终止执行
            boolean isBreak = item.end && !dateTo.equals(date);
            date = dateTo;
            if (isBreak) {
                break;
            }
        }
        // 将正常格式的时间字符串转换为时间
        return new SimpleDateFormat(DATETIME_FULL_FORMAT).parse(String.valueOf(date));
    }

    /**
     * 获取时间格式
     */
    public static void main(String[] args) throws ParseException {
        System.out.println(getAutoDate("1987-11-04"));
        System.out.println(getAutoDate("1987-11-04 12:50"));
        System.out.println(getAutoDate("1987-11-04 12:50:15"));
        System.out.println(getAutoDate("1987-11-04 12:50:15.000"));
        System.out.println(getAutoDate("19871104"));
        System.out.println(getAutoDate("04/11/1987"));
    }
}