by Michael S. Kaplan, published on 2012/04/02 07:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2012/04/02/10289808.aspx
The locale-specific formatting support supported by the NLS API in Windows works via two different (semi-complementary) methods:
For an example of #1 in dates, there are settings like LOCALE_SDATE that tells you what the separator character is between pieces of the short date and LOCALE_IDATE that tells you how the month/day/year pieces are ordered.
For an example of #2 in dates, there are the many per-locale format strings that are defined.
Now over time we have heavily de-emphasized category #1 for dates and times.
Because of how incomplete they are.
And how easy it is to confuse the NLS API about what the settings are when you use simple yet unexpected custom formats.
For example, if you use two different separators between hours/minutes and between minutes/seconds, then the LOCALE_STIME value has no one single value it can return.
Or, for another example, if the month, day and year are in some order other than month/day/year or day/month/year or year/month/day, then the LOCALE_IDATE is kind of screwed trying to decide what value to return.
And so on.
By now and as of Vista and Windows 7, the bulk of the POSIX fields for date and time formatting have now been removed from the locale data.
So if you get them or set them then the code under the NLS API deals with the default format strings, converting between the formats and the POSIX settings as needed.
In either direction.
A side effect of this design is that bugs that used to be possible when the settings were out of sync go away automatically -- such bugs were not rampant in prior versions, but they did come up from time to time.
The MS Visual C Runtime largely depends on the POSIX settings for its own date/time parsing and formatting, so I guess in a way it's good that the POSIX support exists.
And it's even better that the data synchronization bugs were pretty much removed!
Now even though the format strings are superior to the POSIX settings, they too have limitations. I'll talk about those some other day.
For now I'll end today's blog on a high note.
You know, the high note that the current level of support implies and enforces.
I'll wait until tomorrow to talk about where we still fall a little short....
Simon Buchan on 2 Apr 2012 3:49 PM:
I'm a huge believer in minimizing (canonical) data in an application as a way of avoiding bugs, so this does make me happy (after being sad at you saying how it *used* to work) - but I noticed the problems you bring up with LOCALE_* can still be an issue. Not that you can do much about that!
Michael S. Kaplan on 2 Apr 2012 4:00 PM:
Wait til tomorrow, Simon!
Random832 on 2 Apr 2012 11:41 PM:
I really don't understand your "POSIX" vs not distinction. In the _real_ POSIX world, single character separator settings for dates and times don't exist at all. There's no POSIX equivalent to LOCALE_SDATE, LOCALE_IDATE, LOCALE_STIME - what POSIX has is d_fmt and t_fmt, which are... well, format strings. With hard-coded separators within the format string and none of this "/ becomes LOCALE_SDATE" nonsense.
And it's not clear what else exists in Windows for, for example, decimal points and thousands separators.
Michael S. Kaplan on 3 Apr 2012 12:08 AM:
Well, let's thiink of it as POSIX-style -- to support the CRT style locales. :-)
I'll get to numbers soon -- I was just starting with dates and times....
Michael S. Kaplan on 3 Apr 2012 12:18 AM:
Note that the rule was never for one character separators -- just the assumption that only one kind of separator is used for both parts....
referenced by