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

C# 判斷字串是否為日期格式:正則表達式完整指南

     編輯:關於C#

前言

驗證字串是否符合日期格式是表單驗證、資料匯入常見需求。本文整理常用日期格式的正則表達式,並提供 DateTime.TryParse 等更穩健的替代方案比較。

常用日期正則表達式

1. 斜線分隔格式 (YYYY/MM/DD 或 YY/MM/DD)


\b(?\d{2,4})/(?\d{1,2})/(?\d{1,2})\b
  • \b:字邊界
  • (?...):具名擷取群組
  • \d{2,4}:2-4 位數字 (年)
  • \d{1,2}:1-2 位數字 (月/日)

2. 連字號分隔格式 (YYYY-MM-DD)


\b(?\d{2,4})-(?\d{1,2})-(?\d{1,2})\b

3. 中文格式 (YYYY年MM月DD日)


\b(?\d{2,4})年(?\d{1,2})月(?\d{1,2})日\b

完整驗證類別實作


using System;
using System.Text.RegularExpressions;

public static class DateValidator
{
    // 預編譯正則表達式提升效能
    private static readonly Regex SlashFormat = new Regex(
        @"\b(?\d{2,4})/(?\d{1,2})/(?\d{1,2})\b", 
        RegexOptions.Compiled);
    
    private static readonly Regex DashFormat = new Regex(
        @"\b(?\d{2,4})-(?\d{1,2})-(?\d{1,2})\b", 
        RegexOptions.Compiled);
    
    private static readonly Regex ChineseFormat = new Regex(
        @"\b(?\d{2,4})年(?\d{1,2})月(?\d{1,2})日\b", 
        RegexOptions.Compiled);

    /// 
    /// 檢查字串是否符合任一支援的日期格式
    /// 
    public static bool IsDateFormat(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
            return false;
        
        return SlashFormat.IsMatch(input) 
            || DashFormat.IsMatch(input) 
            || ChineseFormat.IsMatch(input);
    }

    /// 
    /// 嘗試解析日期,回傳 DateTime 與格式類型
    /// 
    public static bool TryParseDate(string input, out DateTime date, out string format)
    {
        date = default;
        format = null;
        
        if (string.IsNullOrWhiteSpace(input))
            return false;

        var match = SlashFormat.Match(input);
        if (match.Success && TryCreateDate(match, out date))
        {
            format = "yyyy/MM/dd";
            return true;
        }

        match = DashFormat.Match(input);
        if (match.Success && TryCreateDate(match, out date))
        {
            format = "yyyy-MM-dd";
            return true;
        }

        match = ChineseFormat.Match(input);
        if (match.Success && TryCreateDate(match, out date))
        {
            format = "yyyy年MM月dd日";
            return true;
        }

        return false;
    }

    private static bool TryCreateDate(Match match, out DateTime date)
    {
        date = default;
        try
        {
            int year = int.Parse(match.Groups["year"].Value);
            int month = int.Parse(match.Groups["month"].Value);
            int day = int.Parse(match.Groups["day"].Value);
            
            // 處理兩位數年份 (假設 00-29 為 2000-2029,30-99 為 1930-1999)
            if (year < 100)
                year += year < 30 ? 2000 : 1900;
            
            date = new DateTime(year, month, day);
            return true;
        }
        catch
        {
            return false;
        }
    }
}

進階驗證:包含日期邏輯合法性

正則表達式僅驗證格式,不保證日期真實存在 (如 2023/02/30)。完整驗證需結合 DateTime.TryParse:


public static bool IsValidDate(string input, out DateTime date)
{
    date = default;
    
    // 先用正則快速篩選格式
    if (!IsDateFormat(input))
        return false;
    
    // 再用 TryParse 驗證實際有效性
    // 需指定格式避免文化特性差異
    string[] formats = { "yyyy/MM/dd", "yy/MM/dd", "yyyy-MM-dd", "yy-MM-dd", 
                         "yyyy年MM月dd日", "yy年MM月dd日" };
    
    return DateTime.TryParseExact(input, formats, 
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.None, out date);
}

效能比較:正則 vs TryParse


using System.Diagnostics;

public void Benchmark()
{
    string[] testCases = { "2023/12/25", "2023-12-25", "2023年12月25日", 
                           "invalid", "2023/13/45", "2023/02/30" };
    int iterations = 100000;
    
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    {
        foreach (var tc in testCases)
            DateValidator.IsDateFormat(tc);
    }
    Console.WriteLine($"正則驗證: {sw.ElapsedMilliseconds} ms");
    
    sw.Restart();
    for (int i = 0; i < iterations; i++)
    {
        foreach (var tc in testCases)
            DateTime.TryParse(tc, out _);
    }
    Console.WriteLine($"TryParse: {sw.ElapsedMilliseconds} ms");
    
    sw.Restart();
    for (int i = 0; i < iterations; i++)
    {
        foreach (var tc in testCases)
            DateValidator.IsValidDate(tc, out _);
    }
    Console.WriteLine($"完整驗證: {sw.ElapsedMilliseconds} ms");
}

/*
典型結果:
正則驗證: 45 ms (最快,但不檢查日期合法性)
TryParse: 120 ms (較慢,但自動處理多種格式)
完整驗證: 180 ms (最慢,但最準確)
*/

常見日期格式對照表

格式名稱正則模式範例適用場景
ISO 8601^\d{4}-\d{2}-\d{2}$2023-12-25API、資料庫、國際標準
斜線分隔^\d{2,4}/\d{1,2}/\d{1,2}$2023/12/25中文習慣、舊系統
連字號分隔^\d{2,4}-\d{1,2}-\d{1,2}$2023-12-25美式、系統日誌
中文完整^\d{2,4}年\d{1,2}月\d{1,2}日$2023年12月25日中文文件、報表
含時間^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$2023-12-25 14:30:00日誌、審計追蹤
Unix Timestamp^\d{10,13}$1703485800系統整合、快取

實務建議:策略選擇指南

  1. 僅需格式檢查:使用預編譯正則表達式,效能最佳
  2. 需轉換為 DateTime:直接使用 DateTime.TryParseExact 指定格式陣列
  3. 使用者輸入驗證:結合正則快速篩選 + TryParse 確認,平衡效能與準確度
  4. 大量資料匯入:批次處理時優先 TryParse,失敗再記錄錯誤細節
  5. 跨文化特性:永遠指定 CultureInfo.InvariantCulture 避免伺服器設定影響

擴充:支援更多格式


public static class ExtendedDateValidator
{
    private static readonly string[] SupportedFormats = 
    {
        "yyyy/MM/dd", "yy/MM/dd",
        "yyyy-MM-dd", "yy-MM-dd",
        "yyyy.MM.dd", "yy.MM.dd",
        "yyyy年MM月dd日", "yy年MM月dd日",
        "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm:ss",
        "yyyy/MM/dd HH:mm:ss", "yyyy-MM-ddTHH:mm:ss"
    };

    public static bool TryParseFlexible(string input, out DateTime date)
    {
        return DateTime.TryParseExact(input, SupportedFormats,
            System.Globalization.CultureInfo.InvariantCulture,
            System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date);
    }
}

總結

日期格式驗證有三層次:正則表達式驗證格式 (快但不準)、TryParse 驗證可解析性 (準但慢)、完整驗證包含邏輯合法性 (最準但最慢)。實務上建議根據場景選擇:使用者介面即時驗證用正則,資料處理管線用 TryParseExact 指定格式。預編譯正則、指定文化特性、處理兩位數年份歧義是關鍵細節。

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