C#中如何以最宽松的方式解析日期时间?
针对你处理RSS源时遇到的多格式日期解析难题,我有几个实用的C#方案推荐,不用完全从头实现:
1. 优先用
DateTime.TryParseExact结合多格式+多区域文化 这是最可控的方案——先收集你遇到的(以及RSS常见的)所有日期格式,再搭配对应区域的文化信息,循环尝试解析。这种方式既能覆盖已知格式,也能处理像荷兰语本地化日期(Donderdag 17 juli 2018)这类场景。
示例代码:
public static DateTime ParseRssDateTime(string input) { if (string.IsNullOrWhiteSpace(input)) return DateTime.UtcNow; // 收集所有需要支持的日期格式(可根据实际遇到的格式扩展) var dateFormats = new[] { "dd-MM-yyyy HH.mm", "dddd dd MMMM yyyy, HH:mm", "dd MMM yyyy", "HH:mm dd.MM.yyyy", "yyyy-MM-dd'T'HH:mm:sszzz", "yyyy-MM-dd'T'HH:mm:ssz", "R", // RSS常用的RFC1123格式 "ddd, dd MMM yyyy HH:mm:ss zzz" // 另一种常见的RFC变体 }; // 支持的区域文化(根据RSS源的来源地区扩展,比如添加de-DE、fr-FR等) var cultures = new[] { CultureInfo.InvariantCulture, new CultureInfo("nl-NL"), // 处理荷兰语的星期、月份 new CultureInfo("en-US"), new CultureInfo("en-GB") }; // 先尝试精确匹配已知格式 foreach (var culture in cultures) { if (DateTime.TryParseExact( input.Trim(), dateFormats, culture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out var parsedDate)) { return parsedDate; } } // 精确匹配失败,尝试更宽松的解析 foreach (var culture in cultures) { if (DateTime.TryParse( input.Trim(), culture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out var parsedDate)) { return parsedDate; } } // 所有解析失败,触发回退机制 return DateTime.UtcNow; }
关键细节:
- 添加
DateTimeStyles.AdjustToUniversal确保解析结果统一为UTC时间,避免时区混乱; AllowWhiteSpaces可以忽略输入中多余的空格、制表符,适配格式中的空格差异;- 可根据实际遇到的新格式,随时扩展
dateFormats数组,比如添加德语、法语的本地化格式。
2. 进阶方案:利用第三方库简化解析
如果不想手动维护格式列表,可以试试专门处理日期解析的库,比如NodaTime——它的LocalDatePattern和ZonedDateTimePattern支持更灵活的多格式匹配,对本地化日期的处理也更智能。
比如用NodaTime解析荷兰语日期的示例:
var pattern = ZonedDateTimePattern.CreateWithInvariantCulture( "dddd dd MMMM yyyy, HH:mm", DateTimeZoneProviders.Tzdb); var result = pattern.Parse("donderdag 13 november 2018, 14:32"); if (result.Success) { var utcDateTime = result.Value.ToDateTimeUtc(); }
3. 保留回退机制
正如你提到的,没有方案能覆盖所有极端格式,所以保留DateTime.UtcNow作为最终回退是非常必要的,避免解析失败导致程序异常。
内容的提问来源于stack exchange,提问作者Dirk Boer
相关产品推荐
相关产品推荐

