The dates are recorded as follows in the logs:
08 груд. 2017 00:00:06,694
I've been using Linqpad to try to come up with a valid date time mask using the Ukrainian culture, and this is what I've tried:
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);
This does not work, and the output from this script is:
1/1/0001 12:00:00 AM
This same approach has worked well for me for several other languages, so I'm puzzled as to what is happening here. As best as I can tell, the month is not being parsed correctly. I've try substituting "hrud." for the month value (from: https://www.loc.gov/aba/pcc/conser/conserhold/Mosabbr.html), but that does not work either.
MMMM format specifier for month means "full month name". You can see what are full month names for given culture with:
var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.MonthNames;
For this culture, december full name is "грудень", not "груд". You might think to use "short month name" format specifier MMM. You can look "short names" for month for given culture like this:
var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.AbbreviatedMonthNames;
However you will see that short name for december is "гру" and still not "груд". So to parse your string with default month names for your culture you need to either do:
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);
Or
var dateString = "08 гру. 2017 00:00:06,694";
DateTime date;
DateTime.TryParseExact(dateString, @"dd MMM. yyyy HH:mm:ss,fff", new CultureInfo("uk-UA"), DateTimeStyles.None, out date);
Another option is to adjust culture month names for your case, like this (note that it will not modify global culture settings, only month name for this particular CultureInfo instance, so there is no danger in doing this):
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);
As others have mentioned, MMMM is the full month name and MMM is the three-character abbreviated month name, so neither will work out of the box. Rather than hard-code month names or modify the CultureInfo, I'd prefer to pre-process the string to truncate the month to the 3 characters parseable with the MMM custom format string, either with regular expressions (heavyweight) or directly:
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", ...) ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With