LCID vs. Powerman and the Locale-name-go-round

by Michael S. Kaplan, published on 2007/06/11 03:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2007/06/11/3221177.aspx


(If you can tell what CD is playing over here in the background right now, be sure to give yourself two cool points!)

ph_arnaud asks over in the Suggestion Box:

Are there Win32 (Win2000/XP) functions that convert from LCID to Culture names with same result as CultureInfo class in managed code?

For example:

           ci = new CultureInfo(1041);
           Console.WriteLine("{0} {1}", ci.LCID, ci.Name);

results in "ja-JP"

However, Mlang->GetLcidFromRfc1766()
and the Mlang function LcidToRfc1766W() both return "ja"

Even though it is a 'close' result, the same result would be helpful in some conditions.

I find some LCIDs return the same value (or almost the same except for capitalization) between CultureInfo and the Mlang functions:

           1033 en-US
           2058 es-MX
           2052 zh-CN
           1028 zh-TW
           1046 pt-BR

But for many LCIDs the result is different (not exhaustive list, but just some more examples of differences), Mlang results do not include country name part:

           1042 ko
           1029 cs
           1038 hu
           1045 pl
           1049 ru
           1036 fr
           1031 de
           1040 it
           1034 es

I tried the Win32 API LCIDToLocaleName, and this does work the same as CultureInfo (gives the language-country name) for all these LCIDs.  This would be a good choice, but unfortunately this API is Vista only, and our app must still run on XP.

thanks,

Ah, luckily there is that Microsoft National Language Support Downlevel APIs 1.0 out there and ready to be downloaded, huh? :-)

This library provides downlevel versions of the LCID/name and name/LCID mapping functions.

I have previously talked about this library in my Nobody likes change post, and although I think it is not perfect (ref: A way better model for features, part 2), it certainly helps provide the mappings that are being asked about here.

The differences that are being noted here are due to two different traditions....

The MLang methods return names based on the tradition expressed in What's up with the language names?, while the .NET/Vista names are based on the later tradition that essentially repudiates the earlier one that I described in Yesterday's 'justified design' is tomorrow's 'bug we fixed'.

Of course this is not completely true (the culture names also come from a very different place than the MLang names based on the old RFC), but the shorter names in MLang results are shorter for the same reason -- the full name is not needed to minimally represent things for those languages.

With the distinction now considered irrelevant going forward, I gues it just makes for a curious factoid any time someone notices the difference in behavior!

In any case, the downlevel library will provide the name/LCID mapping for all platforms on which it is supported....

 

This post brought to you by วพ (U+01fe, a.k.a. LATIN CAPITAL LETTER O WITH STROKE AND ACUTE)


ph_arnaud on 11 Jun 2007 11:59 AM:

Thanks for the info, sorry I didn't find your other posts when doing a few related searches.

This solves most of the issue, now I've learned about the XP function that gives the same result as the Vista-only version.

However in examining all the languages that are interesting to us, there is still one difference between the result with the CultureInfo constructor, and these downlevel (or Vista only functions)!

1034, CultureInfo constructor, by default (with no further specifications of sort) tells us "es-ES", while the downlevel functions return "es-ES_tradnl" for the same LCID...  there's always one last troublesome one - this time it wasn't zh-CN or zh-TW though...

Michael S. Kaplan on 11 Jun 2007 12:07 PM:

You have to use CultureInfo.CompareInfo.Name to get the full name including the sort for "alternate sort" locales/cultures like this one (which 0x040a is, as I discussed here).


go to newer or older post, or back to index or month or day