Visual Basic Locale/Regionalization Routines

EnumDateFormats: Regional Locale Date Settings
Posted:   Saturday May 16, 1999
Updated:   Monday December 26, 2011
Applies to:   VB5, VB6
Developed with:   VB6, Windows NT4
OS restrictions:   None
Author:   VBnet - Randy Birch


SetLocaleInfo: Change System Long and Short Date Formats
WM_TIMECHANGE: Detect System Changes to the Date/Time
RegQueryValueEx: Identify Time Zones by Time Zone Bias
EnumDateFormats: Regional Locale Date Settings
EnumTimeFormats: Regional Locale Time Settings
GetLocaleInfo: Regional Locale Date Settings
VB5 or VB6.

The national language support functions let applications set the locale for the system and/or user, identifying the language in which the system/user carries out work and retrieves strings, representing times, dates, and other information, that are correctly formatted for the given language and location of the world. National language support also includes support for keyboard layouts and language-specific fonts.

Windows provides a method - EnumDateFormats - that allows the developer to interrogate the system to retrieve the date formats valid for that system via EnumDateFormatsProc. Where EnumDateFormats is passed the LCID of the system obtained through GetSystemDefaultLCID, the values returned represent formats applicable to the system. When GetUserDefaultLCID is used, the values represent those that may contain customizations to the formats made by the currently logged-on user. GetUserDefaultLCID is defined identically to GetSystemDefaultLCID.

The EnumDateFormatsProc function is an application defined-callback function used with the EnumDateFormats function. It receives a pointer to a string buffer containing a date format string. The DATEFMT_ENUMPROC type defines a pointer to this callback function. EnumDateFormatsProc is a placeholder for the application defined-function name.

The single value returned from the callback - lpDateFormatString - is a pointer to a string buffer containing a null-terminated date format string. This string is a long or short date format, depending on the value of the dwFlags parameter passed to EnumDateFormats. Note that lpDateFormatString should be an LPWSTR for the Unicode (W) version of EnumDateFormats, and an LPSTR for the ANSI (A) version of EnumDateFormats.

The date format strings are translated from Unicode to ANSI, for the ANSI version of this function, based on the default ANSI code page for the LCID. However, if LOCALE_USE_CP_ACP is specified as the dwFlags member, the translation is done using the system default ANSI code page.

 BAS Module Code
Add the following code to a BAS module:

Option Explicit
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Public Const DATE_LONGDATE As Long = &H2
Public Const DATE_SHORTDATE As Long = &H1
Public Const LOCALE_SLANGUAGE As Long = &H2 'localized name of language
Public Const LOCALE_SSHORTDATE As Long = &H1F 'short date format string
Public Const LOCALE_SLONGDATE As Long = &H20 'long date format string
Public Declare Function GetThreadLocale Lib "kernel32" () As Long

Public Declare Function GetSystemDefaultLCID Lib "kernel32" () As Long

Public Declare Function GetLocaleInfo Lib "kernel32" _
   Alias "GetLocaleInfoA" _
  (ByVal Locale As Long, _
   ByVal LCType As Long, _
   ByVal lpLCData As String, _
   ByVal cchData As Long) As Long

Public Declare Function EnumDateFormats Lib "kernel32" _
   Alias "EnumDateFormatsA" _
  (ByVal lpDateFmtEnumProc As Long, _
   ByVal Locale As Long, _
   ByVal dwFlags As Long) As Long

Public Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (Destination As Any, _
   Source As Any, _
   ByVal Length As Long)

Public Function EnumDatesProc(lpDateFormatString As Long) As Long

  'application-defined callback function for EnumDateFormats

   Dim buffer As String
   Dim pos As Integer
  'pad a string to hold the format
   buffer = Space$(256)
  'copy the string pointed to by the return value
   CopyMemory ByVal buffer, lpDateFormatString, ByVal Len(buffer)
  'add to the list
   pos = InStr(buffer, Chr$(0))
   If pos Then
      buffer = Left$(buffer, pos - 1)
   End If
   Form1.List1.AddItem "   " & buffer
  'and return 1 to continue enumeration 
  'until completed (or return 0 to stop)
   EnumDatesProc = 1
End Function

Public Function GetUserLocaleInfo(ByVal dwLocaleID As Long, _
                                  ByVal dwLCType As Long) As String

   Dim sReturn As String
   Dim r As Long

  'call the function passing the Locale type
  'variable to retrieve the required size of
  'the string buffer needed
   r = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
  'if successful..
   If r Then
     'pad the buffer with spaces
      sReturn = Space$(r)
     'and call again passing the buffer
      r = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
     'if successful (r > 0)
      If r Then
        'r holds the size of the string
        'including the terminating null
         GetUserLocaleInfo = Left$(sReturn, r - 1)
      End If
   End If
End Function

 Form Code
Create a form containing 3 textboxes (Text1-Text3), a command button (Command1) and a listbox (List1). Label as desired, and add the following code to the form:

Option Explicit
Private Sub Form_Load()

   Command1.Caption = "Enum Date Formats"
End Sub

Private Sub Command1_Click()

   Dim LCID As Long
  'get the system's locale ID. Where the 
  'user's locale ID is required, call 
  'GetUserLocaleLCID instead.
   LCID = GetSystemDefaultLCID()
  'show localized name of language
   Text1.Text = GetUserLocaleInfo(LCID, LOCALE_SLANGUAGE)
  'add a list caption, and enumerate the
  'available long date formats
   List1.AddItem "Long date formats:"
   Call EnumDateFormats(AddressOf EnumDatesProc, LCID, DATE_LONGDATE)
  'add a list caption, and enumerate the
  'available long date formats
   List1.AddItem ""
   List1.AddItem "Short date formats:"
   Call EnumDateFormats(AddressOf EnumDatesProc, LCID, DATE_SHORTDATE)
  'Show the Long date format string for the LCID in use
   Text2.Text = GetUserLocaleInfo(LCID, LOCALE_SLONGDATE)
  'Show the Short date format string for the LCID in use
   Text3.Text = GetUserLocaleInfo(LCID, LOCALE_SSHORTDATE)

End Sub
Save the program and run. The values displayed should correspond to the Codepage and Regional Settings for your system.
While the GetSystemDefaultLCID function retrieves the system default locale identifier, this is often inappropriate or insufficient in a networked environment or under an operating system where multiple locales have been installed. For example, it is possible for a network admin rolling out a standard image to have the user's default locale set to one differing from the base OS installation, and thus the system default locale.

In this situation Windows' provides an alternate API you can use to obtain the LCID for the current user ... GetUserDefaultLCID. Defined identically to GetSystemDefaultLCID, GetUserDefaultLCID function retrieves the current user's default–locale identifier, and is therefore the most appropriate API to use when it is the user's locale you are interested in, rather than that of the system.


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy



Hit Counter