Given a specific country code, e.g. "CH", how can I get a CultureInfo object? The specific country code is dynamic (changes at runtime). I only have the country code, and i want to know if it is possible to create a CultureInfo object from just the country code. It doesn't matter which exact culture I get (fr-CH/de-CH).
I'm trying do something like this:
CultureInfo c = CultureInfo.CreateSpecificCulture("CH");
Would it be possible to create a culture from a RegionInfo object? Then it would look like this:
RegionInfo r= new RegionInfo("CH");
CultureInfo c = CultureInfo.CreateSpecificCulture(r);
Obviously the preceding examples don't compile, they just give an idea of what I'm trying to achieve.
If you only have the country code, you could use something like this to get all culture infos associated with that country:
var cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures)
.Where(c => c.Name.EndsWith("-CH"));
EDIT: adding -
before CH
to prevent an edge case, as pointed out by @JeppeStigNielsen (see comments below).
Are you trying to create a CultureInfo object ? like this:
CultureInfo c = new CultureInfo("de-CH"); //culture for German (Switzerland)
CultureInfo c = new CultureInfo("fr-CH"); //culure for French (Switzerland)
CultureInfo c = new CultureInfo("it-CH"); //culture for Italian (Switzerland)
Maybe this link can be useful http://www.csharp-examples.net/culture-names/ it show all Cultures.
Of course this is an ugly thing to do because a country (including your example "CH"
Switzerland) can have many languages.
Still, I will offer you two ugly methods. First one:
static IEnumerable<CultureInfo> FindCandidateCultures(RegionInfo region)
{
return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
.Where(x => (new RegionInfo(x.Name)).GeoId == region.GeoId);
}
When used on your particular example, new RegionInfo("CH")
, it gives, on my version of the .NET Framework and my Windows version:
de-CH: German (Switzerland) fr-CH: French (Switzerland) gsw-CH: Alsatian (Switzerland) it-CH: Italian (Switzerland) rm-CH: Romansh (Switzerland) wae-CH: Walser (Switzerland)
Edit: A later version gives the above, plus these two:
en-CH: English (Switzerland) pt-CH: Portuguese (Switzerland)
The second method I will offer you:
// ugly reflection, this can break any day!
static CultureInfo ConvertToCulture(RegionInfo region)
{
var data = typeof(RegionInfo).GetField("m_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(region);
var name = (string)(data.GetType().GetProperty("SNAME", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(data));
return CultureInfo.GetCultureInfo(name);
}
As is evident, it uses internal representations of mscorlib.dll
, and we never know if it will break with future versions. But it does give you a way to pick a particular culture. On my machine, from new RegionInfo("CH")
, you get it-CH: Italian (Switzerland)
.
Edit: Unsurprisingly, the second method has changed in some versions of .NET. Something like:
var data = typeof(RegionInfo).GetField("_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(region);
var name = (string)(data.GetType().GetProperty("CultureName", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(data));
or (if you use nullable reference types) with a lot of !
:
var data = typeof(RegionInfo).GetField("_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
!.GetValue(region);
var name = (string)(data!.GetType().GetProperty("CultureName", BindingFlags.NonPublic | BindingFlags.Instance)
!.GetValue(data)!);
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