C# I';我试图从日志文件中解析乌克兰日期/时间字符串

C# I';我试图从日志文件中解析乌克兰日期/时间字符串,c#,C#,日志中记录的日期如下: 08Гаа。2017 00:00:06694 我一直在使用Linqpad尝试使用乌克兰文化制作一个有效的日期时间掩码,这就是我所尝试的: var dateString = "08 груд. 2017 00:00:06,694"; DateTime date; DateTime.TryParseExact( dateString, "dd MMMM. yyyy HH:mm:ss,fff", new CultureInfo("uk-UA"),

日志中记录的日期如下:

08Гаа。2017 00:00:06694

我一直在使用Linqpad尝试使用乌克兰文化制作一个有效的日期时间掩码,这就是我所尝试的:

var dateString = "08 груд. 2017 00:00:06,694";
DateTime date;

DateTime.TryParseExact(
    dateString, 
    "dd MMMM. yyyy HH:mm:ss,fff",
    new CultureInfo("uk-UA"), 
    DateTimeStyles.None, 
    out date);

Console.WriteLine(date);
这不起作用,此脚本的输出为:

1/1/0001 12:00:00 AM


同样的方法也适用于其他几种语言,所以我对这里发生的事情感到困惑。据我所知,这个月没有被正确解析。我尝试用“hrud.”替换月份值(from:),但这也不起作用。

MMMM
月份格式说明符表示“完整的月份名称”。您可以使用以下工具查看给定区域性的完整月份名称:

var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.MonthNames;
对于这种文化,12月的全名是“Γааа”,而不是“Γаа”。您可能会考虑使用“短月份名称”格式说明符
MMM
。对于给定的区域性,您可以查找月份的“短名称”,如下所示:

var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.AbbreviatedMonthNames;
然而,您会看到12月的简称是“ГППП”,但仍然不是“ГППП”。因此,要使用区域性的默认月份名称解析字符串,您需要执行以下操作之一:

var dateString = "08 грудень 2017 00:00:06,694";
DateTime date;            
DateTime.TryParseExact(dateString, @"dd MMMM yyyy HH:mm:ss,fff", new CultureInfo("uk-UA"), DateTimeStyles.None, out date);

另一个选项是调整案例的区域性月份名称,如下所示(请注意,它不会修改全局区域性设置,只修改此特定
CultureInfo
实例的月份名称,因此这样做没有危险):


正如其他人所提到的,
MMMM
是完整的月份名称,
MMM
是三个字符的缩写月份名称,因此两者都不适用。与硬编码月份名称或修改
CultureInfo
不同,我更喜欢预处理字符串,将月份截断为可使用
MMM
自定义格式字符串解析的3个字符,使用正则表达式(重量级)或直接:

var sb = new StringBuilder (date.Length) ;
var nc = 0 ;
foreach (var ch in date)
{
    if (char.IsLetter (ch) && nc++ >= 3) continue ;
    sb.Append (ch) ;
}
return DateTime.ParseExact ("dd MMM. yyyy HH:mm:ss,fff", ...) ;
var dateString = "08 груд. 2017 00:00:06,694";
DateTime date;
var culture = new CultureInfo("uk-UA");
var defaultShortNames = culture.DateTimeFormat.AbbreviatedMonthNames;
var defaultShortGenitiveNames = culture.DateTimeFormat.AbbreviatedMonthGenitiveNames;
// obviously modify all month names as necessary
defaultShortNames[11] = "Груд";
defaultShortGenitiveNames[11] = "груд";
culture.DateTimeFormat.AbbreviatedMonthNames = defaultShortNames;
culture.DateTimeFormat.AbbreviatedMonthGenitiveNames = defaultShortGenitiveNames; 
// store this modified culture and reuse when necessary
// that MMM format consists of 3 letters is irrelevant - it will still
// work fine with abbreviated month names of 4 characters or more
DateTime.TryParseExact(dateString, @"dd MMM. yyyy HH:mm:ss,fff", culture, DateTimeStyles.None, out date);
var sb = new StringBuilder (date.Length) ;
var nc = 0 ;
foreach (var ch in date)
{
    if (char.IsLetter (ch) && nc++ >= 3) continue ;
    sb.Append (ch) ;
}
return DateTime.ParseExact ("dd MMM. yyyy HH:mm:ss,fff", ...) ;