文章編號: 221542 - 上次校閱: 2004年11月8日 - 版次: 3.1

如何使用 Visual Basic 來變更時區資訊

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

有時候是以程式設計方式變更系統的時區所需執行應用程式。本文將告訴您,這項技術。

其他相關資訊

以下是實作這種效果的方式:
  1. 決定您想要將變更為哪一個時區。
  2. 找不到機碼在登錄中包含 TIME_ZONE_INFORMATION 結構中填入所需的資訊。
  3. 該資訊中讀取和載入 TIME_ZONE_INFORMATION 型別的變數的值。
  4. 呼叫傳遞 TIME_ZONE_INFORMATION 結構變數 「 SetTimeZoneInformation API。
在包含時區資訊的登錄位置不同 Windows 之間 9 x 和 Windows NT/Windows 2000。

Windows NT 和 Windows 2000,是位於:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time 區域
對於 Windows 9 x 它是位於:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Time 區域
時區機碼名稱不同 Windows NT、 Windows 2000 和 Windows 之間 9x 也因為 Windows NT 和 Windows 2000 附加字串"標準時間"到不同的按鍵而 Windows 9 x 並不會。

例如:

在 Windows NT 和 Windows 2000,您將會看到這個機碼:
太平洋標準時間
在 Windows 9 x,而您會看到這個機碼:
太平洋
是可以找到目前的日期/時間設定的登錄位置:
HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

逐步範例

下列程式碼範例需要具有一個清單方塊的表單。清單方塊會載入與使用者可以選取與按兩下滑鼠,若要變更的時區可能時區值。它會顯示 messagebox,一次關閉會變更的系統設定為原始值。
  1. 建立新的標準 EXE 專案。預設會建立 Form1。
  2. 將清單方塊控制項加入至 Form1。
  3. 將下列程式碼加入至 Form1 的一般宣告區段:
    Option Explicit
    
    ' Operating System version information declares
    
    Private Const VER_PLATFORM_WIN32_NT = 2
    Private Const VER_PLATFORM_WIN32_WINDOWS = 1
    
    Private Type OSVERSIONINFO
            dwOSVersionInfoSize As Long
            dwMajorVersion As Long
            dwMinorVersion As Long
            dwBuildNumber As Long
            dwPlatformId As Long
            szCSDVersion As String * 128 ' Maintenance string
    End Type
    
    Private Declare Function GetVersionEx Lib "kernel32" _
    Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
    
    ' Time Zone information declares
    
    Private Type SYSTEMTIME
       wYear As Integer
       wMonth As Integer
       wDayOfWeek As Integer
       wDay As Integer
       wHour As Integer
       wMinute As Integer
       wSecond As Integer
       wMilliseconds As Integer
    End Type
    
    Private Type REGTIMEZONEINFORMATION
       Bias As Long
       StandardBias As Long
       DaylightBias As Long
       StandardDate As SYSTEMTIME
       DaylightDate As SYSTEMTIME
    End Type
    
    Private Type TIME_ZONE_INFORMATION
       Bias As Long
       StandardName(0 To 63) As Byte ' used to accommodate Unicode strings
       StandardDate As SYSTEMTIME
       StandardBias As Long
       DaylightName(0 To 63) As Byte ' used to accommodate Unicode strings
       DaylightDate As SYSTEMTIME
       DaylightBias As Long
    End Type
    
    Private Const TIME_ZONE_ID_INVALID = &HFFFFFFFF
    Private Const TIME_ZONE_ID_UNKNOWN = 0
    Private Const TIME_ZONE_ID_STANDARD = 1
    Private Const TIME_ZONE_ID_DAYLIGHT = 2
    
    Private Declare Function GetTimeZoneInformation Lib "kernel32" _
    (lpTimeZoneInformation As TIME_ZONE_INFORMATION) As Long
    
    Private Declare Function SetTimeZoneInformation Lib "kernel32" _
    (lpTimeZoneInformation As TIME_ZONE_INFORMATION) As Long
    
    ' Registry information declares
    Private Const REG_SZ As Long = 1
    Private Const REG_BINARY = 3
    Private Const REG_DWORD As Long = 4
    
    Private Const HKEY_CLASSES_ROOT = &H80000000
    Private Const HKEY_CURRENT_USER = &H80000001
    Private Const HKEY_LOCAL_MACHINE = &H80000002
    Private Const HKEY_USERS = &H80000003
    
    Private Const ERROR_SUCCESS = 0
    Private Const ERROR_BADDB = 1
    Private Const ERROR_BADKEY = 2
    Private Const ERROR_CANTOPEN = 3
    Private Const ERROR_CANTREAD = 4
    Private Const ERROR_CANTWRITE = 5
    Private Const ERROR_OUTOFMEMORY = 6
    Private Const ERROR_ARENA_TRASHED = 7
    Private Const ERROR_ACCESS_DENIED = 8
    Private Const ERROR_INVALID_PARAMETERS = 87
    Private Const ERROR_NO_MORE_ITEMS = 259
    
    Private Const KEY_ALL_ACCESS = &H3F
    
    Private Const REG_OPTION_NON_VOLATILE = 0
    
    Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
       Alias "RegOpenKeyExA" ( _
       ByVal hKey As Long, _
       ByVal lpSubKey As String, _
       ByVal ulOptions As Long, _
       ByVal samDesired As Long, _
       phkResult As Long) _
    As Long
    
    Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
       Alias "RegQueryValueExA" ( _
       ByVal hKey As Long, _
       ByVal lpszValueName As String, _
       ByVal lpdwReserved As Long, _
       lpdwType As Long, _
       lpData As Any, _
       lpcbData As Long) _
    As Long
    
    Private Declare Function RegQueryValueExString Lib "advapi32.dll" _
       Alias "RegQueryValueExA" ( _
       ByVal hKey As Long, _
       ByVal lpValueName As String, _
       ByVal lpReserved As Long, _
       lpType As Long, _
       ByVal lpData As String, _
       lpcbData As Long) _
    As Long
    
    Private Declare Function RegEnumKey Lib "advapi32.dll" _
       Alias "RegEnumKeyA" ( _
       ByVal hKey As Long, _
       ByVal dwIndex As Long, _
       ByVal lpName As String, _
       ByVal cbName As Long) _
    As Long
    
    Private Declare Function RegCloseKey Lib "advapi32.dll" ( _
       ByVal hKey As Long) _
    As Long
    
    ' Registry Constants
    Const SKEY_NT = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
    Const SKEY_9X = "SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
    
    ' The following declaration is different from the one in the API viewer.
    ' To disable implicit ANSI<->Unicode conversion, it changes the 
    ' variable types of lpMultiByteStr and lpWideCharStr to Any.
    '
    Private Declare Function MultiByteToWideChar Lib "kernel32" ( _
        ByVal CodePage As Long, _
        ByVal dwFlags As Long, _
        lpMultiByteStr As Any, _
        ByVal cchMultiByte As Long, _
        lpWideCharStr As Any, _
        ByVal cchWideChar As Long) As Long
        
    ' The above Declare and the following Constants are used to make
    ' this sample compatible with Double Byte Character Systems (DBCS).
    Private Const CP_ACP = 0
    Private Const MB_PRECOMPOSED = &H1
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ 
    ByRef Destination As Any, _
    ByRef Source As Any, _
    ByVal numbytes As Long)
    Dim SubKey As String
    
    Private Sub Form_Load()
       Dim lRetVal As Long, lResult As Long, lCurIdx As Long
       Dim lDataLen As Long, lValueLen As Long, hKeyResult As Long
       Dim strvalue As String
       Dim osV As OSVERSIONINFO
    
    ' Win9x and WinNT have a slightly different registry structure. Determine
    ' the operating system and set a module variable to the correct subkey.
    
       osV.dwOSVersionInfoSize = Len(osV)
       Call GetVersionEx(osV)
       If osV.dwPlatformId = VER_PLATFORM_WIN32_NT Then
          SubKey = SKEY_NT
       Else
          SubKey = SKEY_9X
       End If
    
       lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SubKey, 0, _
                              KEY_ALL_ACCESS, hKeyResult)
    
       If lRetVal = ERROR_SUCCESS Then
    
          lCurIdx = 0
          lDataLen = 32
          lValueLen = 32
    
          Do
             strvalue = String(lValueLen, 0)
             lResult = RegEnumKey(hKeyResult, lCurIdx, strvalue, lDataLen)
    
             If lResult = ERROR_SUCCESS Then
                List1.AddItem Left(strvalue, lValueLen)
             End If
    
             lCurIdx = lCurIdx + 1
    
          Loop While lResult = ERROR_SUCCESS
    
          RegCloseKey hKeyResult
       Else
          List1.AddItem "Could not open registry key"
       End If
    End Sub
    
    Private Sub List1_DblClick()
       Dim TZ As TIME_ZONE_INFORMATION, oldTZ As TIME_ZONE_INFORMATION
       Dim rTZI As REGTIMEZONEINFORMATION
       Dim bytDLTName(32) As Byte, bytSTDName(32) As Byte
       Dim cbStr As Long, dwType As Long
       Dim lRetVal As Long, hKeyResult As Long, lngData As Long
    
       lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SubKey & "\" & List1.Text, _
                               0, KEY_ALL_ACCESS, hKeyResult)
    
       If lRetVal = ERROR_SUCCESS Then
          lRetVal = RegQueryValueEx(hKeyResult, "TZI", 0&, ByVal 0&, _
                                      rTZI, Len(rTZI))
    
          If lRetVal = ERROR_SUCCESS Then
             TZ.Bias = rTZI.Bias
             TZ.StandardBias = rTZI.StandardBias
             TZ.DaylightBias = rTZI.DaylightBias
             TZ.StandardDate = rTZI.StandardDate
             TZ.DaylightDate = rTZI.DaylightDate
    
             cbStr = 32
             dwType = REG_SZ
    
             lRetVal = RegQueryValueEx(hKeyResult, "Std", _
                         0&, dwType, bytSTDName(0), cbStr)
    
             If lRetVal = ERROR_SUCCESS Then
                Call MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _
                   bytSTDName(0), cbStr, TZ.StandardName(0), 32)
             Else
                RegCloseKey hKeyResult
                Exit Sub
             End If
    
             cbStr = 32
             dwType = REG_SZ
    
             lRetVal = RegQueryValueEx(hKeyResult, "Dlt", _
                         0&, dwType, bytDLTName(0), cbStr)
    
             If lRetVal = ERROR_SUCCESS Then
                Call MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _
                   bytDLTName(0), cbStr, TZ.DaylightName(0), 32)
             Else
                RegCloseKey hKeyResult
                Exit Sub
             End If
    
             lRetVal = GetTimeZoneInformation(oldTZ)
    
             If lRetVal = TIME_ZONE_ID_INVALID Then
                MsgBox "Error getting original TimeZone Info"
                RegCloseKey hKeyResult
                Exit Sub
             Else
             If TZ.DaylightDate.wMonth <> 0 And TZ.DaylightBias <> 0 Then
                lRetVal = SetTimeZoneInformation(TZ)
             Else
               Call CopyMemory(TZ.DaylightName(0), TZ.StandardName(0), 64)
               TZ.DaylightBias = 0
               lRetVal = SetTimeZoneInformation(TZ)
             End If
                MsgBox "Time Zone Changed, Click OK to restore"
                lRetVal = SetTimeZoneInformation(oldTZ)
             End If
          End If
    
          RegCloseKey hKeyResult
       End If
    End Sub
    					
  4. 執行該程式,並請注意清單方塊會顯示所有可用的時區。
  5. 選取時間區域,然後連按兩下。您的系統地區設定變更為選取的區域。您會收到下列訊息:
    時區已變更的按一下 [確定] 來還原
  6. 在控制台中按兩下 [日期/時間] 圖示。您也可以藉由連按兩下系統匣中的時鐘到達此對話方塊。按一下 [時區] 索引標籤然後觀察已變更的時區。
  7. 關閉 [日期/時間內容] 對話方塊,然後按一下 [應用程式所顯示的訊息方塊上的 [確定]]。重複前一個步驟,以確認時區資訊已被還原。

這篇文章中的資訊適用於:
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
關鍵字:?
kbmt kbapi kbhowto KB221542 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:221542? (http://support.microsoft.com/kb/221542/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。