DateTime.Parse的奇怪行为

我们有一个很大的应用程序(不幸的是)使用了DateTime.Parse(text)。 用更好的东西替换DateTime.Parse现在不是一个选项。

最近我升级了Windows(到Windows 10)并开始出现问题。 根据https://msdn.microsoft.com/en-us/library/system.datetime.parse(v=vs.110).aspx上的文档,该方法应使用CultureInfo.CurrentCulture作为默认格式提供者。 在我的电脑上似乎并非如此,除非我遗漏了一些明显的东西。

以下代码调用函数两次,首先不更改任何文化设置,然后在文化和ui文化上设置挪威文化。 出于某种原因,它能够解析在两种情况下以en-US格式(M / d / yyyy)给出的文本,但是它无法以CultureInfo期望的格式解析日期。

这里发生了什么? 我希望我错过了一些明显的东西……

class Program { static void Main(string[] args) { var norwegianCulture = new CultureInfo("nb-NO"); Console.WriteLine("First"); ParseDates(); Console.WriteLine("\nSecond"); Thread.CurrentThread.CurrentUICulture = norwegianCulture; ParseDates(); Console.ReadKey(); } private static void ParseDates() { Console.WriteLine($"CultureInfo.CurrentCulture: {CultureInfo.CurrentCulture}"); Console.WriteLine($"CultureInfo.CurrentUICulture: {CultureInfo.CurrentUICulture}"); Console.WriteLine($"{Thread.CurrentThread.CurrentCulture} - CurrentCulture - {Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern}"); Console.WriteLine($"{Thread.CurrentThread.CurrentUICulture} - CurrentUICulture - {Thread.CurrentThread.CurrentUICulture.DateTimeFormat.ShortDatePattern}"); var shortDateString = new DateTime(2015, 9, 5).ToShortDateString(); WriteParsedDate(shortDateString); WriteParsedDate("1/2/2015"); Console.WriteLine(); } private static void WriteParsedDate(string shortDateString) { try { var d = DateTime.Parse(shortDateString, CultureInfo.CurrentCulture); Console.WriteLine($"The text {shortDateString} parsed to Year: {d.Year}, Month: {d.Month}, Day: {d.Day}"); } catch (Exception e) { Console.WriteLine($"The text {shortDateString} could not be parsed."); Console.WriteLine($"Error: {e.Message}"); } } } 

将此内容写入控制台:

 First CultureInfo.CurrentCulture: nb-NO CultureInfo.CurrentUICulture: en-US nb-NO - CurrentCulture - dd.MM.yyyy en-US - CurrentUICulture - M/d/yyyy The text 05.09.2015 could not be parsed. Error: String was not recognized as a valid DateTime. The text 1/2/2015 parsed to Year: 2015, Month: 2, Day: 1 Second CultureInfo.CurrentCulture: nb-NO CultureInfo.CurrentUICulture: nb-NO nb-NO - CurrentCulture - dd.MM.yyyy nb-NO - CurrentUICulture - dd.MM.yyyy The text 05.09.2015 could not be parsed. Error: Strengen ble ikke gjenkjent som en gyldig DateTime. The text 1/2/2015 parsed to Year: 2015, Month: 2, Day: 1 

部分解决方法

正如shf301所写,这是由于Windows 10中的一个错误。

我设法通过从“。”更改时间分隔符来使其工作。 到“:” – 与旧版本的Windows一样。 我猜它正在使用该更改,因为我们只使用用户设置,而不是手动加载/指定它们。

这是一个列出Connect的漏洞。 对于具有相同日期和时间分隔符的任何区域设置, 似乎日期解析失败。

 Estonian (Estonia) Finnish (Finland) Norwegian Bokmål (Norway) Norwegian Bokmål (Svalbard and Jan Mayen) Serbian (Cyrillic, Kosovo) Serbian (Latin, Montenegro) Serbian (Latin, Serbia) Serbian (Latin, Kosovo) 

您的示例从不使用美国设置解析或格式化日期。 首先,没有IFormatProvider DateTime.Parse使用CurrentCulture而不是CurrentUICulture ,其次你明确地将CurrentCulture传递给DateTime.Parse 。 这就是两种情况下输出完全相同的原因。

如果使用en-US规则解析"1/2/2015" ,它将输出:

 The text 1/2/2015 parsed to Year: 2015, Month: 1, Day: 2 

DateTime.Parse只是很聪明,并假设您使用/作为日期分隔符而不是. 并将日期解析为d/M/yyyy

在修复此问题之前,您将不得不将调用更改为DateTime.Parse 。 或者切换到不受影响的.Net 3.5或更早版本。