dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

CultureInfo gives incorrect information #101383

Closed MdeBruin93 closed 6 months ago

MdeBruin93 commented 6 months ago

Description

The CultureInfo class gives wrong information.

I'm not sure how many Cultures are affected by this, but this doesn't seem right.

Schermafbeelding 2024-04-22 160334

Reproduction Steps

Create a console app using .NET 8 template. Insert code: `var cult = CultureInfo.GetCultureInfo("BEL");

var tmp = cult.DisplayName; Console.WriteLine(cult.ThreeLetterISOLanguageName); Console.WriteLine(tmp);

var cult2 = CultureInfo.GetCultureInfo("BLR"); Console.WriteLine(cult2.ThreeLetterISOLanguageName); Console.WriteLine(cult2.DisplayName);`

Expected behavior

When instantiating the CultureInfo class with the 3 letter ISO code "BEL" I expect to get the display name "Belgum". And with "BLR" I expect to get "Belarus".

Actual behavior

When instantiating the CultureInfo class with the 3 letter ISO code "BEL" I'm getting the display name "Belarus" which is incorrect.

Regression?

I reckon it worked before, but I haven't touched these classes in quite some time so can't tell you when it started.

Known Workarounds

No response

Configuration

No response

Other information

No response

dotnet-policy-service[bot] commented 6 months ago

Tagging subscribers to this area: @dotnet/area-system-globalization See info in area-owners.md if you want to be subscribed.

danmoseley commented 6 months ago

Is it possible to check the result on some older .NET versions, like 7 and 6..

MdeBruin93 commented 6 months ago

I've just tested it with those versions. .NET 7 also give me the same bug, .NET 6 does show the correct values for these Cultures. I have not tested other Cultures.

tarekgh commented 6 months ago

When instantiating the CultureInfo class with the 3 letter ISO code "BEL" I expect to get the display name "Belgum". And with "BLR" I expect to get "Belarus".

The culture instantiation is not designed to use 3-letter ISO code. It is designed to use the BCP-47 tags https://en.wikipedia.org/wiki/IETF_language_tag. If you want to get specific culture with the desired 3-letter ISO code, you can do:

            foreach (CultureInfo c in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
            {
                if (c.ThreeLetterISOLanguageName.Equals("BEL", StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine($"{c.Name} ... {c.DisplayName} ... {c.EnglishName} ... {c.NativeName} ... {c.ThreeLetterISOLanguageName} ... {c.ThreeLetterWindowsLanguageName} ... {c.TwoLetterISOLanguageName}");
                }
            }

            // print: be-BY ... Belarusian (Belarus) ... Belarusian (Belarus) ... беларуская (Беларусь) ... bel ... BEL ... be

I am closing this issue. Feel free to send any more questions if you have any.

tarekgh commented 6 months ago

To note, there is RegionInfo class which can be used to instantiate with the two letters ISO code of any region. Like doing var r = new RegionInfo("BE"); which will create Belgium region object. or you can enumerate cultures to see which one match the 3-letter ISO code as

            foreach (CultureInfo c in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
            {
                var ri = new RegionInfo(ci.Name);
                if (ri.ThreeLetterISORegionName.Equals("BEL", StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine($"{ri.Name} ... {ri.DisplayName} ... {ri.EnglishName} ... {ri.NativeName} ... {ri.ThreeLetterISORegionName} ... {ri.ThreeLetterWindowsRegionName} ... {ri.TwoLetterISORegionName}");
                    break;
                }
            }