C#:将字符串转换为日期时间

C#:将字符串转换为日期时间,c#,datetime,tryparse,C#,Datetime,Tryparse,我想分析带有日期的字符串,这些字符串可以有不同的格式,如: “2012年12月21日”、“2011年11月4日”、“2011年6月30日”、“2013年12月16日”、“2013年4月”、“2012年4月12日”、“2011年马尔兹12日” 我有以下代码: string[] ll = {"en-US", "de-DE"}; date = "4,12,2011"; foreach (string l in ll) { if (DateTime.TryParse(date, new Cult

我想分析带有日期的字符串,这些字符串可以有不同的格式,如:

“2012年12月21日”、“2011年11月4日”、“2011年6月30日”、“2013年12月16日”、“2013年4月”、“2012年4月12日”、“2011年马尔兹12日”

我有以下代码:

string[] ll = {"en-US", "de-DE"}; 
date = "4,12,2011";
foreach (string l in ll) {
   if (DateTime.TryParse(date, new CultureInfo(l),
                            DateTimeStyles.None, out pDate)) {
       return pDate;//.ToString("dd.MM.yyyy");
   }
}
我对这样的约会有问题:

“21.12.12”的解析方式类似于“2012年12月21日”,这是正常的

“41221011”的解析方式类似于“2011年4月12日”,它不正常,我需要“2011年12月4日”

如何设置日和月的订单?


必须在月的前一天

指定要传递的字符串的格式,您应该使用该方法。

要指定要传递的字符串的格式,您应该使用该方法。

这是针对
en-US
文化的。对我们欧洲人来说,这可能很奇怪,但美国人确实是在日复一日地写日期。您可以改用
en GB
——它将处理相同的月份名称和欧洲订单。

这是针对
en US
文化的。对我们欧洲人来说,这可能很奇怪,但美国人确实是在日复一日地写日期。您可以改用
en GB
——它将根据您的代码处理相同的月份名称和欧洲订单。

  string[] ll = {"en-US", "de-DE"}; 
您最初尝试使用“en-US”文化解析日期时间;因此,“4122111”将被解析 正如美国人所做的那样——年月日——第一个月(4月12日)。更改数组中的顺序

  string[] ll = {"de-DE", "en-US"}; 

根据您的代码,“4122001”将是12月4日

  string[] ll = {"en-US", "de-DE"}; 
您最初尝试使用“en-US”文化解析日期时间;因此,“4122111”将被解析 正如美国人所做的那样——年月日——第一个月(4月12日)。更改数组中的顺序

  string[] ll = {"de-DE", "en-US"}; 

“4,122011”将是12月4日

使用
DateTime.ParseExact
,它还有一个重载,允许为所有允许的格式传递
字符串[[]

string[] dates = new[] { "21.12.12", "4,12,2011", "30 Jun 11", "16 12 2013", "April 2013", "12. April 2012", "12, März 2011" };
CultureInfo germanCulture = CultureInfo.CreateSpecificCulture("de-DE"); // you are using german culture
string[] formats = new[] { "dd/MM/yy", "d,MM,yyyy", "dd MMM yy", "dd MM yyyy", "MMMM yyyy", "dd. MMMM yyyy", "dd, MMMM yyyy"};

foreach (string dateString in dates)
{
    DateTime dt = DateTime.ParseExact(dateString, formats, germanCulture, DateTimeStyles.None);
    Console.WriteLine(dt.ToString());
}

我使用了德语区域性,因为您的日期字符串包含德语月份名称。因此,即使当前区域性不同,此代码也有效。

使用
DateTime.ParseExact
,它还有一个重载,允许为所有允许的格式传递
字符串[[]

string[] dates = new[] { "21.12.12", "4,12,2011", "30 Jun 11", "16 12 2013", "April 2013", "12. April 2012", "12, März 2011" };
CultureInfo germanCulture = CultureInfo.CreateSpecificCulture("de-DE"); // you are using german culture
string[] formats = new[] { "dd/MM/yy", "d,MM,yyyy", "dd MMM yy", "dd MM yyyy", "MMMM yyyy", "dd. MMMM yyyy", "dd, MMMM yyyy"};

foreach (string dateString in dates)
{
    DateTime dt = DateTime.ParseExact(dateString, formats, germanCulture, DateTimeStyles.None);
    Console.WriteLine(dt.ToString());
}

我使用了德语区域性,因为您的日期字符串包含德语月份名称。因此,即使当前区域性不同,此代码仍然有效。

您提供的所有测试日期实际上都在您指定的
de
区域性中正确解析。问题在于,您首先尝试在美国区域性中解析它,在那里它们是se
mm.dd.yyyy
样式格式

通常,正确的解决方案是始终确保在解析字符串时知道所使用的区域性,而不是猜测。如果必须猜测,有时会遇到此类问题


在这种情况下,虽然看起来它们都是可以接受的日期字符串,所以您可以直接解析它们,而不需要尝试不同文化的循环(正如前面提到的,这可能永远不会是一个完美的结果)

通常,正确的解决方案是始终确保在解析字符串时知道所使用的区域性,而不是猜测。如果必须猜测,有时会遇到此类问题


在这种情况下,虽然看起来它们都是可以接受的日期字符串,所以您可以直接解析它们,而不需要尝试不同文化的循环(正如前面提到的,这可能永远不会是一个完美的结果).

4,122011对于4月12日和12月4日都是有效字符串。除非您指定格式,否则代码无法知道哪一个是有效字符串。我发誓,这已经被问了很多次了。它肯定是重复的。4,122011对于4月12日和12月4日都是有效字符串。代码无法知道哪一个是非有效字符串除非你指定了格式。我发誓,这个问题被问了很多次。它肯定是重复的。但是如果你不知道确切的格式是什么,这没有帮助,除非你能建议代码很乐意解析“21.12.12”和“12.April 2012”同样容易…文化是前进的方向…问题是为什么要麻烦使用parse-exact并指定许多不同的格式,而不仅仅是使用parse,让它尝试所有它能想到的格式,如果你解决了文化问题的话…@Chris ok,现在我明白了:)你完全正确,+1来自我的答案。但是如果你不知道确切的格式是什么,除非你能推荐一些代码来解析“21.12.12”和“12.April 2012”同样容易…文化是一条路…重点是为什么要麻烦使用parse-exact并指定许多不同的格式,而不仅仅是使用parse,让它尝试所有它能想到的格式,如果你解决了文化问题的话…@Chris ok,现在我明白了:)你完全正确,我给你的答案加1。你是的如果您具有正确的区域性,则不需要精确解析。使用
parse
de
区域性,所有这些字符串都可以工作,而不必尝试用格式覆盖所有可能性。如果您具有正确的区域性,则不需要精确解析。使用
parse
de
区域性,所有这些字符串都可以与ut必须尝试用格式覆盖每一种可能性。+1表示“所有日期解析正确”,即使我的文化是“de de”)@TimSchmelter:我进行测试主要是因为我很好奇为什么en-us会出现在那里。这显然是问题的原因,所以我试图找出它还有什么问题需要解决。然后我发现它是