by Michael S. Kaplan, published on 2010/10/26 07:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2010/10/26/10080726.aspx
The other day, in a comment to I Triple Adar you!, regular reader Mihai said:
Trivia: did you know that GetLocaleInfo/GetLocaleInfoEx never returns anything for LOCALE_SMONTHNAME13? (and in general any LOCALE_S*MONTHNAME13)
This is very true, and in its own way not actually trivial!
The logic of this is kind of weird.
One might say it is Microsoft-style logic, kind of.
It's a design issue I first ran across in a significant way when the CultureAndRegionInfoBuilder class was being designed.
It starts with the GetLocaleInfoEx Function. Like it's older cousin, it has lots of constants for grabbing months, from the LOCALE_SABBREVMONTHNAME* constants to the LOCALE_SMONTHNAME* constants.
There are 13 there for each set, the last one from each is:
LOCALE_SMONTHNAME13 | Native name for a 13th month, if it exists. The maximum number of characters allowed for this string is 80, including a terminating null character. |
LOCALE_SABBREVMONTHNAME13 |
Native abbreviated name for a 13th month, if it exists. The maximum number of characters allowed for this string is 80, including a terminating null character. |
But there is a problem here. The problem is that the GetLocaleInfoEx Function only ever is returning information about the Gregorian calendar.
So that text above, that goes on about "for a 13th month, if it exists" for these two items.
Well, it is true. 100% of the time that the Gregorian calendar has a 13th month, this field will contain the info.
Because it can't ever happen.
Similarly, the CultureAndRegionInfoBuilder's DateTimeFormat is a GregorianDateTimeFormat. Because the locale model itself can' ever handle more than the Gregorian calendar. The other calendars are stored separately, in a place that doesn't support localization (as I first pointed out in Calendars on Win32 -- Not all there yet nearly six years ago. It is just a real lameness and limitation of the model.
So sure, the GetCalendarInfoEx Function can find occasional use for a CAL_ABBREVMONTHNAME13 or CAL_MONTHNAME13, because sometimes it will be needed.
But LOCALE_SABBREVMONTHNAME13 and LOCALE_SMONTHNAME13 are like those folks I met in Los Angeles last Saturday who say they are actors but never go on auditions or casting calls, so they never actually get a chance to work as actors.
LOCALE_SABBREVMONTHNAME13 and LOCALE_SMONTHNAME13 are pretty much doomed to that same fate, never finding any work in their claimed profession. Waiting for hacks, and living an empty [string] life....
Awfully optimistic of the documentation though, huh? :-)
Mihai on 26 Oct 2010 11:52 AM:
> The problem is that the GetLocaleInfoEx Function only ever is returning information about the Gregorian calendar.
That actually s*ks big time, design or not.
Because the APIs can take the user locale as parameter, and since that can be customized to use an alternate calendar, I would expect results about the stuff that I am asking (and for some Arabic locales the default calendar is non-Gregorian, so there is no need for customization).
And the code does not fully implements the design, because comparing the results for default set to Japanese vs. Japanese with Japanese calendar I get different results (for LOCALE_SSHORTDATE, LOCALE_SLONGDATE, LOCALE_SYEARMONTH, LOCALE_ICALENDARTYPE, LOCALE_ICENTURY, LOCALE_IDAYLZERO, LOCALE_IMONLZERO).
And "gg y'年'M'月'd'日'" is definitely not a Gregorian pattern :-)
Anyway, the workaround works indeed (should take the result from LOCALE_ICALENDARTYPE and use GetCalendarInfo/GetCalendarInfoEx)
Michael S. Kaplan on 26 Oct 2010 2:58 PM:
I agree -- the design should be improved here; I just doubt it will ever happen. :-(
referenced by