RegisterLog In/Log OutView Cart
O'Reilly Ron's VB Forum Ron's VB Forum
BooksSafari BookshelfConferencesO'Reilly NetworkO'Reilly GearLearning Lab
 


Traveling to
a tech show?

Hotel Search
Hotel Discounts
Discount Hotels
Chicago Hotels
Canada Hotels
California Hotels
Hotels




Date: Apr 7 1999
From: Norman
To: ron@oreilly.com
Subject: Changing the Regional Short Date format in VB

Ron,

This isn't really documented very well in Microsoft's Technet or MSDN. I want to write a VB program to change the machine's ShortDate in its Regional Settings under Windows 95 to "mm/dd/yyyy" as the default is "m/d/yy" for the USA regional settings. This old setting will cause Y2K issues. Rather than change 600+ workstations by hand via the Control Panel "Regional Settings" Date settings, I would rather write a VB 5.0 program that runs from a Server Login script.

Any ideas?

-- Norman


Hello Norman,

Actually, I've always wondered how to retrieve and set the date and time format from Visual Basic, and have constantly included it as an action item on my "to do" list. But evidently, I've never really wanted to know badly enough to find out, since it's remained a perpetual action item. That was the situation when your question arrived, and a very good question it is.

I had thought that the answer would be shrouded in obscurity and mystery, and require the use of either the registry or the initialization file functions in the Win32 API, along with some spying tools to see from where Windows was retrieving its regional settings. As it turns out, though, that's really unnecessary; as Visual Basic programmers, we just don't pay much attention to regional settings because Visual Basic -- for better or for worse -- handles them for us, and so their operation is somewhat mysterious to us.

But in fact, a single Win32 function, SetLocaleInfo, can be used to set a wide range of regional settings. On success, the function returns a non-zero value; otherwise, it returns zero (or False). Its C language prototype is:


BOOL SetLocaleInfo(LCID Locale,

     LCTYPE LCType, LPCTSTR lpLCData);

where the parameters are the following:

  • LCID Locale -- The locale whose setting is to be changed.

  • LCTYPE LCType -- A single LCTYPE constant representing the regional setting to be changed. These are declared in WINNLS.H. For your purpose in setting the short date format, you're interested in only one constant:

    
    #define LOCALE_SSHORTDATE   0x0000001F
    
    

  • LPCTSTR lpLCData -- A pointer to a string containing the new setting. Here again, for your purpose, this is simply the standard short date format "MM/dd/yyyy".

Of course, it would be just too simple if we were to change the system's date format unconditionally; instead, we have to provide the locale identifier whose short date format we want to change. This, however, is easily retrieved from the Win32 GetSystemDefaultLCID function; its prototype is:


LCID GetSystemDefaultLCID();

To translate all of this to Visual Basic, we have to add the following in the declarations section of our project's code module:


Public Const LOCALE_SSHORTDATE = &H1F



Public Declare Function GetSystemDefaultLCID _

        Lib "kernel32" () As Long



Public Declare Function SetLocaleInfo Lib _

     "kernel32" Alias "SetLocaleInfoA" ( _

     ByVal Locale As Long, _

     ByVal LCType As Long, _

     ByVal lpLCData As String) As Boolean

Note that you want to use the ByVal keyword in passing lpLCData to the function, since you want to pass a pointer to a null-terminated C string; if you pass the argument by reference, you end up passing a pointer to a Visual Basic string, which will have rather unfortunate consequences.

Once you've figured out which Win32 API functions to call, changing the setting is simplicity itself:


Private Sub Main()



Dim lngLocale As Long



lngLocale = GetSystemDefaultLCID()



If SetLocaleInfo(lngLocale, _

      LOCALE_SSHORTDATE, _

      "MM/dd/yyyy") = _

      False Then

   ' Handle error, possibly by writing it 

   ' to a server error log

End If



End Sub

There are a couple of embellishments that you might want to make to the basic code. Since the utility will run transparently to the user, you'll want to log failures on the server rather than notify a no doubt astonished user. And presumably you want to call the PostMessage function to notify other applications that a Windows system setting has changed (although I've never noticed that it really makes a difference).

Thanks for your question. And for helping me remove one rather long-standing item from my "to do" list.

--Ron

Return to: Ron's VB Forum



O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.