Changing DateSeparator doesn't work for all CultureInfos

Viewed 128

I am trying to change the DateSeparator and it doesn't work for all cultures. Below, I'm trying to format a date in the Japanese and Korean Cultures and use an underscore for the date separator. It works as expected for Japan, but not for Korea. I've found some other cultures that behave this way as well.

CultureInfo jpCulture = CultureInfo.CreateSpecificCulture("jp");
DateTimeFormatInfo jpFormat = jpCulture.DateTimeFormat;
jpFormat.DateSeparator = "_";

CultureInfo koCulture = CultureInfo.CreateSpecificCulture("ko");
DateTimeFormatInfo koFormat = koCulture.DateTimeFormat;
koFormat.DateSeparator = "_";

string jpDate = DateTime.Now.ToString("d", jpFormat);
string koDate = DateTime.Now.ToString("d", koFormat);

System.Console.WriteLine($"My local (US) formatting: {DateTime.Now:d} - JP Formatter: {jpDate} - KO Formatter: {koDate}");

Will output:

My local (US) formatting: 8/3/2020 - JP Formatter: 08_03_2020 - KO Formatter: 2020-08-03

I had expected the Korean formatted string to use underscores as well.

My goal is to always have a Date format that's appropriate for the culture (YMD, or MDY or DMY) but using a customizable separator. Is there a more appropriate way to do that?

2 Answers

This happens because the d standard date/time format specifier uses the DateTimeFormat.ShortDatePattern to produce the output string. Only a "/" character in the pattern will be replaced by the locale's DateSeparator.

If you add the following to your test application:

Console.WriteLine(koCulture.DateTimeFormat.ShortDatePattern);
Console.WriteLine(jpCulture.DateTimeFormat.ShortDatePattern);

you will see the following output:

yyyy-MM-dd
MM/dd/yyyy

The Japanese string contains the "/" character that will be replaced by DateTimeFormat.DateSeparator, so that works.

The Korean one, however, uses - - which won't be replaced!

A possible workaround is to change the Korean short date format like so:

koCulture.DateTimeFormat.ShortDatePattern = koCulture.DateTimeFormat.ShortDatePattern.Replace('-', '/');

(although that feels a bit flaky to me...)

As to why the Korean short date pattern is set up like this, I have no idea. It seems like a bug, but only Microsoft could answer that!

It looks like loads of the cultures have "incorrect" ShortDatePattern values where Microsoft has put in the actual date separator character rather than a "/" character, as the following code shows:

foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    var dtf = culture.DateTimeFormat;

    if (dtf.DateSeparator != "/" && dtf.ShortDatePattern.Contains(dtf.DateSeparator))
        Console.WriteLine(culture.EnglishName + " has incorrect short date pattern: " + dtf.ShortDatePattern);
}

There is a problem with DateSeparator, only / is replaced with specified separator, this can be seen in source.

For any culture with ShortDatePattern containing other separator than / the DateSeparator is not working.

Related