|
This sample provides a drop-in ready class module, which you can use in either Classic VB or VBA to determine the regional settings currently in use. You have the option to override the user's preferred settings, as well, to determine what the default regional settings for this machine should be. Also, you may (hopefully with the user's permission!) change the current user's preference for regional settings.
The CLocaleInfo class will use Unicode functions by default, when they're available, and ANSI functions when it finds itself operating under older (Win9x) platforms. Using this class is extremely simple. For example:
Dim li As CLocaleInfo Set li = New CLocaleInfo li.AllowUserOverride = True Debug.Print Format$(Now, li.LocaleInfo(LOCALE_SLONGDATE))Note however that there isn't always a direct 1:1 correspondence between VB's custom formatting strings and those used by Windows. For example, Windows uses "t" or "tt" to represent "A/P" or "AM/PM", so you can't directly pass LOCALE_STIMEFORMAT to the native Format function without some massaging of the results. In order to avoid these messy situations, I added two more functions to the class which show how to call the API functions GetTimeFormat and GetDateFormat. These are as simple to use as this:
Debug.Print li.LocaleDate(, , DATE_LONGDATE); " at "; Debug.Print li.LocaleTime()All the constants used with the Locale functions are conveniently exposed as public enumerations. These are available for your inspection:
Public Enum LocaleInfoTypes LOCALE_ILANGUAGE = &H1 ' language id LOCALE_SLANGUAGE = &H2 ' localized name of language LOCALE_SENGLANGUAGE = &H1001 ' English name of language LOCALE_SABBREVLANGNAME = &H3 ' abbreviated language name LOCALE_SNATIVELANGNAME = &H4 ' native name of language LOCALE_ICOUNTRY = &H5 ' country code LOCALE_SCOUNTRY = &H6 ' localized name of country LOCALE_SENGCOUNTRY = &H1002 ' English name of country LOCALE_SABBREVCTRYNAME = &H7 ' abbreviated country name LOCALE_SNATIVECTRYNAME = &H8 ' native name of country LOCALE_IDEFAULTLANGUAGE = &H9 ' default language id LOCALE_IDEFAULTCOUNTRY = &HA ' default country code LOCALE_IDEFAULTCODEPAGE = &HB ' default code page LOCALE_SLIST = &HC ' list item separator LOCALE_IMEASURE = &HD ' 0 = metric, 1 = US LOCALE_SDECIMAL = &HE ' decimal separator LOCALE_STHOUSAND = &HF ' thousand separator LOCALE_SGROUPING = &H10 ' digit grouping LOCALE_IDIGITS = &H11 ' number of fractional digits LOCALE_ILZERO = &H12 ' leading zeros for decimal LOCALE_SNATIVEDIGITS = &H13 ' native ascii 0-9 LOCALE_SCURRENCY = &H14 ' local monetary symbol LOCALE_SINTLSYMBOL = &H15 ' intl monetary symbol LOCALE_SMONDECIMALSEP = &H16 ' monetary decimal separator LOCALE_SMONTHOUSANDSEP = &H17 ' monetary thousand separator LOCALE_SMONGROUPING = &H18 ' monetary grouping LOCALE_ICURRDIGITS = &H19 ' # local monetary digits LOCALE_IINTLCURRDIGITS = &H1A ' # intl monetary digits LOCALE_ICURRENCY = &H1B ' positive currency mode LOCALE_INEGCURR = &H1C ' negative currency mode LOCALE_SDATE = &H1D ' date separator LOCALE_STIME = &H1E ' time separator LOCALE_SSHORTDATE = &H1F ' short date format string LOCALE_SLONGDATE = &H20 ' long date format string LOCALE_STIMEFORMAT = &H1003 ' time format string LOCALE_IDATE = &H21 ' short date format ordering LOCALE_ILDATE = &H22 ' long date format ordering LOCALE_ITIME = &H23 ' time format specifier LOCALE_ICENTURY = &H24 ' century format specifier LOCALE_ITLZERO = &H25 ' leading zeros in time field LOCALE_IDAYLZERO = &H26 ' leading zeros in day field LOCALE_IMONLZERO = &H27 ' leading zeros in month field LOCALE_S1159 = &H28 ' AM designator LOCALE_S2359 = &H29 ' PM designator LOCALE_SDAYNAME1 = &H2A ' long name for Monday LOCALE_SDAYNAME2 = &H2B ' long name for Tuesday LOCALE_SDAYNAME3 = &H2C ' long name for Wednesday LOCALE_SDAYNAME4 = &H2D ' long name for Thursday LOCALE_SDAYNAME5 = &H2E ' long name for Friday LOCALE_SDAYNAME6 = &H2F ' long name for Saturday LOCALE_SDAYNAME7 = &H30 ' long name for Sunday LOCALE_SABBREVDAYNAME1 = &H31 ' abbreviated name for Monday LOCALE_SABBREVDAYNAME2 = &H32 ' abbreviated name for Tuesday LOCALE_SABBREVDAYNAME3 = &H33 ' abbreviated name for Wednesday LOCALE_SABBREVDAYNAME4 = &H34 ' abbreviated name for Thursday LOCALE_SABBREVDAYNAME5 = &H35 ' abbreviated name for Friday LOCALE_SABBREVDAYNAME6 = &H36 ' abbreviated name for Saturday LOCALE_SABBREVDAYNAME7 = &H37 ' abbreviated name for Sunday LOCALE_SMONTHNAME1 = &H38 ' long name for January LOCALE_SMONTHNAME2 = &H39 ' long name for February LOCALE_SMONTHNAME3 = &H3A ' long name for March LOCALE_SMONTHNAME4 = &H3B ' long name for April LOCALE_SMONTHNAME5 = &H3C ' long name for May LOCALE_SMONTHNAME6 = &H3D ' long name for June LOCALE_SMONTHNAME7 = &H3E ' long name for July LOCALE_SMONTHNAME8 = &H3F ' long name for August LOCALE_SMONTHNAME9 = &H40 ' long name for September LOCALE_SMONTHNAME10 = &H41 ' long name for October LOCALE_SMONTHNAME11 = &H42 ' long name for November LOCALE_SMONTHNAME12 = &H43 ' long name for December LOCALE_SMONTHNAME13 = &H100E ' long name for 13th month (if exists) LOCALE_SABBREVMONTHNAME1 = &H44 ' abbreviated name for January LOCALE_SABBREVMONTHNAME2 = &H45 ' abbreviated name for February LOCALE_SABBREVMONTHNAME3 = &H46 ' abbreviated name for March LOCALE_SABBREVMONTHNAME4 = &H47 ' abbreviated name for April LOCALE_SABBREVMONTHNAME5 = &H48 ' abbreviated name for May LOCALE_SABBREVMONTHNAME6 = &H49 ' abbreviated name for June LOCALE_SABBREVMONTHNAME7 = &H4A ' abbreviated name for July LOCALE_SABBREVMONTHNAME8 = &H4B ' abbreviated name for August LOCALE_SABBREVMONTHNAME9 = &H4C ' abbreviated name for September LOCALE_SABBREVMONTHNAME10 = &H4D ' abbreviated name for October LOCALE_SABBREVMONTHNAME11 = &H4E ' abbreviated name for November LOCALE_SABBREVMONTHNAME12 = &H4F ' abbreviated name for December LOCALE_SABBREVMONTHNAME13 = &H100F ' abbreviated name for 13th month (if exists) LOCALE_SPOSITIVESIGN = &H50 ' positive sign LOCALE_SNEGATIVESIGN = &H51 ' negative sign LOCALE_IPOSSIGNPOSN = &H52 ' positive sign position LOCALE_INEGSIGNPOSN = &H53 ' negative sign position LOCALE_IPOSSYMPRECEDES = &H54 ' mon sym precedes pos amt LOCALE_IPOSSEPBYSPACE = &H55 ' mon sym sep by space from pos amt LOCALE_INEGSYMPRECEDES = &H56 ' mon sym precedes neg amt LOCALE_INEGSEPBYSPACE = &H57 ' mon sym sep by space from neg amt '#if(WINVER >= 0x0400) LOCALE_FONTSIGNATURE = &H58 ' font signature LOCALE_SISO639LANGNAME = &H59 ' ISO abbreviated language name LOCALE_SISO3166CTRYNAME = &H5A ' ISO abbreviated country name '#endif /* WINVER >= 0x0400 */ '#if(WINVER >= 0x0500) LOCALE_IDEFAULTEBCDICCODEPAGE = &H1012 ' default ebcdic code page LOCALE_IPAPERSIZE = &H100A ' 0 = letter, 1 = a4, 2 = legal, 3 = a3 LOCALE_SENGCURRNAME = &H1007 ' english name of currency LOCALE_SNATIVECURRNAME = &H1008 ' native name of currency LOCALE_SYEARMONTH = &H1006 ' year month format string LOCALE_SSORTNAME = &H1013 ' sort name LOCALE_IDIGITSUBSTITUTION = &H1014 ' 0 = none, 1 = context, 2 = native digit '#endif /* WINVER >= 0x0500 */ End Enum ' Time Flags for GetTimeFormatW. Public Enum LocaleTimeFlags TIME_NOMINUTESORSECONDS = &H1 ' do not use minutes or seconds TIME_NOSECONDS = &H2 ' do not use seconds TIME_NOTIMEMARKER = &H4 ' do not use time marker TIME_FORCE24HOURFORMAT = &H8 ' always use 24 hour format End Enum ' Date Flags for GetDateFormatW. Public Enum LocaleDateFlags DATE_SHORTDATE = &H1 ' use short date picture DATE_LONGDATE = &H2 ' use long date picture End EnumYou may notice an odd addition near the end of the module, in the private ForceEnumCase routine. All of these enumerated constants are defined within a conditional compilation block. And, odder still, the test is written such that the block is never compiled! Why? Doing this forces the VB IDE to maintain proper-casing on all these constants. Were they only enumerated, if you typed one manually (rather than choose it from the Intellisense dropdown) and used a different casing, it would change globally throughout your project. I "can't imagine what they were smoking" when they made this design decision in Redmond, can you? Anyway, this trick overrides that idiotic behavior, and doesn't bloat your final EXE at all. VBA users may want to remove the superfluous routine if the added bulk hinders their distribution size.
This sample hasn't been published anywhere except here on this website, but first rights to such publication are jealously guarded - you have been warned. <g>
This sample uses the following API calls:
Module Library Function CLocaleInfo.cls kernel32 GetDateFormat
GetLocaleInfo
GetSystemDefaultLangID
GetTimeFormat
GetVersionEx
SetLocaleInfoDon't see what you're looking for? Here's a complete API cross-reference.
Please, enjoy and learn from this sample. Include its code within your own projects, if you wish. But, in order to insure only the most recent code is available to all, I ask that you don't share the sample by any form of mass distribution. Download Locale.zip, 8Kb, Last Updated: Thursday, March 22, 2007