在C#中将非常长的日期格式解析为DateTime
我如何将以下字符串日期解析为C#中的DateTime对象:
“1970年1月1日星期四”
这来自XML feed,而DateTime.Parse似乎不喜欢它在en-GB语言环境中。 饲料只会来自英国的服务器,所以我不担心全球化问题
我最初的蛮力方法是:
- 删除包括逗号在内的所有内容,以及留下“1970年1月1日”的尾随空格
- 然后根据需要删除“st”,“nd”,“rd”或“th”以留下“1970年1月1日”
- 然后将月份转换为其数字等效值,留下“1 1 1970”
- 然后用“/”替换空格以获得“1/1/1970”
我确定必须有一个更优雅的方式吗? 我无法使DateTime.Prse或Datetime.ParseExact工作
只是为了提供一个略有不同的看法,并让您了解一些其他选择; 你可以指定DateTime.Parse(或我的例子中的TryParse)的格式来解决这样的情况,而不试图用String.Replace
调用等将字符串“预格式化”为其他东西;
public DateTime ParseOrdinalDateTime(string dt) { string[] expectedFormats = DateTime d; if (DateTime.TryParseExact(dt, "dddd, d\"st\" MMMM yyyy", null, DateTimeStyles.None, out d)) return d; if (DateTime.TryParseExact(dt, "dddd, d\"nd\" MMMM yyyy", null, DateTimeStyles.None, out d)) return d; if (DateTime.TryParseExact(dt, "dddd, d\"rd\" MMMM yyyy", null, DateTimeStyles.None, out d)) return d; if (DateTime.TryParseExact(dt, "dddd, d\"th\" MMMM yyyy", null, DateTimeStyles.None, out d)) return d; throw new InvalidOperationException("Not a valid DateTime string"); }
我提出这种方法的原因是它非常清楚地列出了您的输入期望,并且包含了单个方法的行为。 如果格式发生变化,您可以在此处指定不同的格式字符串,并考虑新的日期时间字符串结构。
或者,考虑到以下评论,上述内容略有不同;
private static DateTime ParseOrdinalDateTime(string dt) { string[] expectedFormats = new[] { "dddd, d'st' MMMM yyyy", "dddd, d'nd' MMMM yyyy", "dddd, d'rd' MMMM yyyy", "dddd, d'th' MMMM yyyy" }; try { return DateTime.ParseExact(dt, expectedFormats, null, DateTimeStyles.None); } catch (Exception e) { throw new InvalidOperationException("Not a valid DateTime string", e); } }
注意:我捕获并抛出上面的InvalidOperationException的唯一原因是保护调用者不必catch Exception
来处理DateTime.ParseExact
可能抛出的任何可能的exception。 您可以轻松修改此API。
我不相信DateTime
解析知道有关序数的任何内容,但它应该能够处理其他所有内容。 所以你可以使用:
public static string RemoveOrdinals(string input) { // Ugly but oh so simple. return input.Replace("0th", "0") .Replace("1st", "1") .Replace("2nd", "2") .Replace("3rd", "3") .Replace("11th", "11") // Need to handle these separately... .Replace("12th", "12") .Replace("13th", "13") .Replace("4th", "4") .Replace("5th", "5") .Replace("6th", "6") .Replace("7th", "7") .Replace("8th", "8") .Replace("9th", "9"); }
然后:
string text = RemoveOrdinals(text); DateTime date = DateTime.ParseExact(text, "dddd, d MMMM yyyy", CultureInfo.GetCulture("en-GB"));
(作为一个快速插件,当然你只想要一个日期而不是日期/时间。不幸的是.NET没有代表它的类型 – 但你可以在我的Noda Time库中使用LocalDate
。我们不处理序数或者 – 无论如何 – 所以你仍然需要额外的方法。让我知道你是否想看到相关的代码。)
将DateTime.Parse
与特定于区域性的格式化程序一起使用:
http://msdn.microsoft.com/en-us/library/kc8s65zs.aspx
首先反转这个答案的逻辑,从月中剥离“st”,“nd”等:
https://stackoverflow.com/a/4544313/2420979
然后通常只使用DateTime.Parse
:
var result = DateTime.Parse("Thursday, 1 January 1970", new CultureInfo("en-GB"));