首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 正則表達式實現多格式日期解析與標準化

     編輯:Java 相關知識

前言

在實際開發中,經常需要處理各種格式的日期字串,例如 2014-03-12 12:05:34、2014/3/12 12:5:34、2014年3月12日 13時5分34秒 甚至 13:05:34(僅時間)等。手動編寫大量 if-else 判斷不僅繁瑣,且難以維護。本文介紹一種基於正則表達式與 SimpleDateFormat 結合的通用日期解析工具類,能自動識別多種常見日期格式並統一轉換為標準格式 yyyy-MM-dd HH:mm:ss。

核心設計思路

  1. 正則映射表:預先定義「正則模式 → 對應日期格式」的映射關係,涵蓋帶分隔符、無分隔符、僅時間、僅日期等 14 種常見場景。
  2. 動態匹配:輸入字串遍歷映射表,首個匹配成功的模式即確定解析格式。
  3. 補全上下文:對於「僅時間」(如 13:05:34)或「日.月」(如 21.12)等不完整資訊,自動補上當前日期或年份。
  4. 統一分隔符:將所有非數字字符替換為 -,再由 SimpleDateFormat 解析並格式化輸出。

關鍵代碼實現

public class DateFormatUtil {
    private static final Map<String, String> DATE_REG_FORMAT = new LinkedHashMap<>();

    static {
        // 帶完整時間的各種分隔符格式
        DATE_REG_FORMAT.put("^\\d{4}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D*$", "yyyy-MM-dd-HH-mm-ss");
        DATE_REG_FORMAT.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd-HH-mm");
        DATE_REG_FORMAT.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd-HH");
        DATE_REG_FORMAT.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd");
        DATE_REG_FORMAT.put("^\\d{4}\\D+\\d{2}$", "yyyy-MM");
        DATE_REG_FORMAT.put("^\\d{4}$", "yyyy");
        // 緊湊格式(無分隔符)
        DATE_REG_FORMAT.put("^\\d{14}$", "yyyyMMddHHmmss");
        DATE_REG_FORMAT.put("^\\d{12}$", "yyyyMMddHHmm");
        DATE_REG_FORMAT.put("^\\d{10}$", "yyyyMMddHH");
        DATE_REG_FORMAT.put("^\\d{8}$", "yyyyMMdd");
        DATE_REG_FORMAT.put("^\\d{6}$", "yyyyMM");
        // 僅時間:補當前日期
        DATE_REG_FORMAT.put("^\\d{2}\\s*:\\s*\\d{2}\\s*:\\s*\\d{2}$", "yyyy-MM-dd-HH-mm-ss");
        DATE_REG_FORMAT.put("^\\d{2}\\s*:\\s*\\d{2}$", "yyyy-MM-dd-HH-mm");
        // 兩位年份或日.月格式
        DATE_REG_FORMAT.put("^\\d{2}\\D+\\d{1,2}\\D+\\d{1,2}$", "yy-MM-dd");
        DATE_REG_FORMAT.put("^\\d{1,2}\\D+\\d{1,2}$", "yyyy-dd-MM");
        DATE_REG_FORMAT.put("^\\d{1,2}\\D+\\d{1,2}\\D+\\d{4}$", "dd-MM-yyyy");
    }

    public static String formatDate(String dateStr) {
        String curDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (Map.Entry<String, String> entry : DATE_REG_FORMAT.entrySet()) {
            if (Pattern.compile(entry.getKey()).matcher(dateStr).matches()) {
                DateFormat parser = new SimpleDateFormat(entry.getValue());
                // 補全上下文邏輯
                if (entry.getKey().contains("\\d{2}\\s*:\\s*\\d{2}")) {
                    dateStr = curDate + "-" + dateStr; // 僅時間 → 加上今天日期
                } else if (entry.getKey().equals("^\\d{1,2}\\D+\\d{1,2}$")) {
                    dateStr = curDate.substring(0, 4) + "-" + dateStr; // 日.月 → 加上今年
                }
                // 統一分隔符並解析
                String normalized = dateStr.replaceAll("\\D+", "-");
                try {
                    return targetFormat.format(parser.parse(normalized));
                } catch (ParseException e) {
                    throw new IllegalArgumentException("日期格式無效: " + dateStr, e);
                }
            }
        }
        throw new IllegalArgumentException("不支持的日期格式: " + dateStr);
    }
}

測試驗證

主方法內置 20 組測試用例,涵蓋所有預定義格式,輸出均為標準 yyyy-MM-dd HH:mm:ss。例如:

  • 2014年3月12日 13時5分34秒 → 2014-03-12 13:05:34
  • 13:05:34 → 2024-05-20 13:05:34(假設今天是 2024-05-20)
  • 21.12 → 2024-12-21 00:00:00

優化建議

  • 使用 LinkedHashMap 保持匹配優先級(如完整格式優於簡略格式)。
  • 捕獲 ParseException 並轉為非受檢異常,簡化調用方處理。
  • 若項目使用 Java 8+,建議遷移至 java.time 套件(DateTimeFormatter),線程安全且功能更豐富。

總結

該工具類通過「正則分派 + 格式補全 + 統一解析」三步走策略,優雅地解決了多格式日期解析難題,代碼結構清晰、易於擴展新格式,適合作為項目通用工具類引入。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved