Note to the NLS API: It ain't ever gonna by 13 o'clock, either.

by Michael S. Kaplan, published on 2010/10/26 07:01 -04:00, original URI:

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.


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. :-(

Please consider a donation to keep this archive running, maintained and free of advertising.
Donate €20 or more to receive an offline copy of the whole archive including all images.

referenced by

2011/12/13 These aren't the MONTHS you're looking for (aka You'll never get to the 13th month *that* way)

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