將 "2024-01-15" 或 "2024/01/15" 格式字串轉為 "二〇二四年一月十五日" 格式。
^\d{2,4}[-/]\d{1,2}[-/]\d{1,2}$。- 或 /) 分割年月日。
public sealed class ChineseDateConverter
{
private static readonly Lazy _instance =
new Lazy(() => new ChineseDateConverter());
public static ChineseDateConverter Instance => _instance.Value;
private readonly char[] _digits = { '〇', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十' };
private readonly Regex _dateRegex = new(@"^(\d{2,4})[-/](\d{1,2})[-/](\d{1,2})$", RegexOptions.Compiled);
private ChineseDateConverter() { }
public string Convert(string dateStr)
{
var match = _dateRegex.Match(dateStr);
if (!match.Success) throw new ArgumentException("日期格式錯誤,需 yyyy-MM-dd 或 yyyy/MM/dd");
int year = int.Parse(match.Groups[1].Value);
int month = int.Parse(match.Groups[2].Value);
int day = int.Parse(match.Groups[3].Value);
if (month < 1 || month > 12 || day < 1 || day > 31)
throw new ArgumentException("月份或日期超出範圍");
var sb = new StringBuilder();
// 年
foreach (char c in year.ToString()) sb.Append(_digits[c - '0']);
sb.Append('年');
// 月
sb.Append(ConvertMonth(month));
sb.Append('月');
// 日
sb.Append(ConvertDay(day));
sb.Append('日');
return sb.ToString();
}
private string ConvertMonth(int m)
{
if (m == 10) return "十";
if (m > 10) return "十" + _digits[m - 10];
if (m == 1) return "一"; // 正月慣稱 "一月",非 "正月"
return _digits[m].ToString();
}
private string ConvertDay(int d)
{
if (d == 10) return "十";
if (d == 20) return "二十";
if (d == 30) return "三十";
if (d > 30) return "三十" + _digits[d - 30];
if (d > 20) return "二十" + _digits[d - 20];
if (d > 10) return "十" + _digits[d - 10];
return _digits[d].ToString();
}
}
ChineseDateConverter.Instance.Convert("2024-01-15"); // "二〇二四年一月十五日"
ChineseDateConverter.Instance.Convert("24/12/31"); // "二四年十二月三十一日"
ChineseDateConverter.Instance.Convert("2024-10-10"); // "二〇二四年十月十日"
DateTime 直接輸入:public string Convert(DateTime dt) => Convert(dt.ToString("yyyy-MM-dd"));ChineseLunisolarCalendar。此實作無外部依賴、效能優異、邏輯清晰,適合直接整合至專案中。