Jump to content

Recommended Posts

Posted

TimeZone UDF:

#Region ;**** Directives ****
#include-once
#include <AutoItConstants.au3>
#include <WinAPIConstants.au3>
#EndRegion ;**** Directives ****
;~ #RequireAdmin

#Region ;**** Header ****
; ===============================================================================================================================
; Title .........: TimeZone UDF
; Description ...: Functions to get, set, and manage Windows Time Zones.
;                : Provides methods to set by name (e.g., "SE Asia Standard Time") or by UTC offset (e.g., "UTC+7").
;                : Uses WinAPI (SetDynamicTimeZoneInformation) with a fallback to tzutil.exe.
; Compatibility .: Windows 7 and later.
;                : (Requires SetDynamicTimeZoneInformation API and tzutil.exe, which are not available on Windows XP).
; Author ........: Dao Van Trong - TRONG.PRO
; Version .......: 1.0
;
; ===============================================================================================================================
#EndRegion ;**** Header ****

#Region ;**** Global Variables ****
; Initialize the global time zone array
Global $g_aTimeZones = _TimeZone_pInitArray()
#EndRegion ;**** Global Variables ****

#Region ;**** Public Functions ****

; ===============================================================================================================================
; Function:    _TimeZone_Set($sTimeZone)
; Description: Sets the system's time zone.
; Parameter(s): $sTimeZone - The target time zone. Can be a standard name (e.g., "SE Asia Standard Time")
;              :            or a UTC offset string (e.g., "UTC+7", "+7", "UTC-5.5").
; Return Value: Success - 1
;              : Failure - 0, sets @error:
;              :           1 - Invalid time zone name provided or could not be resolved.
;              :           2 - WinAPI method failed.
;              :           3 - tzutil fallback method also failed.
;              :           4 - Both methods executed, but the time zone did not change.
; Author ......: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_Set($sTimeZone)
    ; Check if the input is a UTC offset and convert it to a standard name
    If StringInStr($sTimeZone, "UTC") > 0 Or StringRegExp($sTimeZone, "^[+-]?\d+\.?\d*$") Then
        $sTimeZone = _TimeZone_ConvertOffsetToName($sTimeZone)
    EndIf
    ; Validate the time zone name
    If $sTimeZone = "" Then
        Return SetError(1, 0, 0) ; Error: Invalid timezone name
    EndIf
    ; Get the current time zone
    Local $sCurrentTZ = _TimeZone_Get()
    ; If already in the target time zone, no change is needed
    If $sCurrentTZ = $sTimeZone Then
        Return 1
    EndIf
    ; Method 1: Attempt to set using WinAPI (Vista+)
    Local $bSuccess = _TimeZone_pSetWinAPI($sTimeZone)
    If $bSuccess Then
        Sleep(500) ; Wait for the system to update
        ; Verify the change
        Local $sNewTZ = _TimeZone_Get()
        If $sNewTZ = $sTimeZone Then
            Return 1 ; Success
        EndIf
        ; If it failed, fall through to tzutil
    EndIf
    ; Fallback: Use tzutil if WinAPI fails or doesn't apply the change
    $bSuccess = _TimeZone_pSetTzUtil($sTimeZone)
    If $bSuccess Then
        Sleep(500) ; Wait for the system to update
        ; Final verification
        Local $sFinalTZ = _TimeZone_Get()
        If $sFinalTZ = $sTimeZone Then
            Return 1 ; Success
        Else
            Return SetError(4, 0, 0) ; Error: tzutil executed but timezone still not changed
        EndIf
    Else
        Return SetError(3, 0, 0) ; Error: Both WinAPI and tzutil methods failed
    EndIf
EndFunc   ;==>_TimeZone_Set

; ===============================================================================================================================
; Function:    _TimeZone_Get()
; Description: Gets the current active time zone name from the system.
; Parameter(s): None
; Return Value: Returns the standard time zone name (e.g., "SE Asia Standard Time").
; Author .....: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_Get()
    Local Const $TIME_ZONE_ID_INVALID = 0xFFFFFFFF
    ; Method 1: Use WinAPI GetDynamicTimeZoneInformation (Vista+)
    Local $tDTZI = DllStructCreate( _
            "long Bias;" & _
            "wchar StandardName[32];" & _
            "word StdYear;word StdMonth;word StdDayOfWeek;word StdDay;word StdHour;word StdMinute;word StdSecond;word StdMilliseconds;" & _
            "long StandardBias;" & _
            "wchar DaylightName[32];" & _
            "word DltYear;word DltMonth;word DltDayOfWeek;word DltDay;word DltHour;word DltMinute;word DltSecond;word DltMilliseconds;" & _
            "long DaylightBias;" & _
            "wchar TimeZoneKeyName[128];" & _
            "byte DynamicDaylightTimeDisabled" _
            )
    Local $aResult = DllCall("kernel32.dll", "dword", "GetDynamicTimeZoneInformation", "ptr", DllStructGetPtr($tDTZI))
    If Not @error And $aResult[0] <> $TIME_ZONE_ID_INVALID Then
        Local $sTZ = DllStructGetData($tDTZI, "TimeZoneKeyName")
        If $sTZ <> "" Then
            Return $sTZ
        EndIf
    EndIf
    ; Fallback 1: Read from Registry
    Local $sTimeZone = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation", "TimeZoneKeyName")
    If Not @error And $sTimeZone <> "" Then
        Return $sTimeZone
    EndIf
    ; Fallback 2: Use tzutil
    Local $iPID = Run(@ComSpec & ' /c tzutil /g', @WindowsDir & '\System32', @SW_HIDE, $STDOUT_CHILD)
    ProcessWaitClose($iPID)
    Local $sOutput = StdoutRead($iPID)
    Return StringStripWS($sOutput, 3)
EndFunc   ;==>_TimeZone_Get

; ===============================================================================================================================
; Function:    _TimeZone_ListAll()
; Description: Lists all available time zones on the system using tzutil.
; Parameter(s): None
; Return Value: A string containing the output from 'tzutil /l'.
; Author .....: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_ListAll()
    Local $sOutput = ""
    Local $iPID = Run(@ComSpec & ' /c tzutil /l', @WindowsDir & '\System32', @SW_HIDE, $STDOUT_CHILD)
    ProcessWaitClose($iPID)
    $sOutput = StdoutRead($iPID)
    Return $sOutput
EndFunc   ;==>_TimeZone_ListAll

; ===============================================================================================================================
; Function:    _TimeZone_ConvertOffsetToName($sUTC)
; Description: Converts a UTC offset string (e.g., "UTC+7" or "+7") to a primary Windows time zone name.
; Parameter(s): $sUTC - The UTC offset string.
; Return Value: Success - A standard Windows time zone name (e.g., "SE Asia Standard Time").
;              : Failure - An empty string "" if no match is found.
; Author ......: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_ConvertOffsetToName($sUTC)
    $sUTC = StringUpper(StringStripWS($sUTC, 8))
    $sUTC = StringReplace($sUTC, "UTC", "")
    Local $fOffset = Number($sUTC)
    ; Find the corresponding time zone
    ; Use the global $g_aTimeZones array
    For $i = 0 To UBound($g_aTimeZones) - 1
        If Abs($g_aTimeZones[$i][0] - $fOffset) < 0.01 Then
            Return $g_aTimeZones[$i][1]
        EndIf
    Next
    ; If not found, try to find the closest match
    Local $fMinDiff = 999
    Local $sClosestTZ = ""
    For $i = 0 To UBound($g_aTimeZones) - 1
        Local $fDiff = Abs($g_aTimeZones[$i][0] - $fOffset)
        If $fDiff < $fMinDiff Then
            $fMinDiff = $fDiff
            $sClosestTZ = $g_aTimeZones[$i][1]
        EndIf
    Next
    If $fMinDiff <= 1 Then
        Return $sClosestTZ
    EndIf
    ; If still not found, return an empty string
    Return ""
EndFunc   ;==>_TimeZone_ConvertOffsetToName

; ===============================================================================================================================
; Function:    _TimeZone_GetNameFromDisplay($sDisplayName)
; Description: Gets the standard time zone name or offset from the display name (city/region).
; Parameter(s): $sDisplayName - The display name (e.g., "Hanoi", "Paris"). This must be an exact match from the
;              :               $g_aTimeZones array (e.g., "Bangkok, Hanoi, Jakarta").
;              : $sInfoType    - "offset" - (Default) Returns the numeric offset (e.g., 7).
;              :               "name"   - Returns the standard name (e.g., "SE Asia Standard Time").
; Return Value: Success - A string containing the requested information.
;              : Failure - An empty string "" if the display name is not found.
; Author ......: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_GetNameFromDisplay($sDisplayName, $sInfoType = "offset")
    For $i = 0 To UBound($g_aTimeZones) - 1
        If $g_aTimeZones[$i][2] == $sDisplayName Then
            Switch $sInfoType
                Case "offset"
                    Return $g_aTimeZones[$i][0]
                Case "name"
                    Return $g_aTimeZones[$i][1]
                Case Else
                    Return $g_aTimeZones[$i][0] ; Default to offset
            EndSwitch
        EndIf
    Next
    Return "" ; Not found
EndFunc   ;==>_TimeZone_GetNameFromDisplay

; ===============================================================================================================================
; Function:    _TimeZone_GetDisplayFromeName($sTimeZoneName)
; Description: Gets the display name (city/region) or offset from the standard time zone name.
; Parameter(s): $sTimeZoneName - The standard time zone name (e.g., "SE Asia Standard Time").
;              : $sInfoType     - "display" - (Default) Returns the display name (e.g., "Bangkok, Hanoi, Jakarta").
;              :                "offset"  - Returns the numeric offset (e.g., 7).
; Return Value: Success - A string containing the requested information.
;              : Failure - An empty string "" if the time zone name is not found.
; Author ......: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_GetDisplayFromeName($sTimeZoneName, $sInfoType = "display")
    For $i = 0 To UBound($g_aTimeZones) - 1
        If $g_aTimeZones[$i][1] == $sTimeZoneName Then
            Switch $sInfoType
                Case "offset"
                    Return $g_aTimeZones[$i][0]
                Case "display"
                    Return $g_aTimeZones[$i][2]
                Case Else
                    Return $g_aTimeZones[$i][2] ; Default to display name
            EndSwitch
        EndIf
    Next
    Return "" ; Not found
EndFunc   ;==>_TimeZone_GetDisplayFromeName

; ===============================================================================================================================
; Function:    _TimeZone_GetInfoFromOffset($fOffset)
; Description: Finds the closest matching time zone information for a given numeric offset.
; Parameter(s): $fOffset   - The numeric offset (e.g., 7, -5, 5.5).
;              : $sInfoType - "all"     - (Default) Returns a formatted string: "(UTC+07:00) Bangkok, Hanoi, Jakarta"
;              :            "offset"  - Returns the formatted offset string (e.g., "UTC+07:00")
;              :            "name"    - Returns the standard name (e.g., "SE Asia Standard Time")
;              :            "display" - Returns the display name (e.g., "Bangkok, Hanoi, Jakarta")
; Return Value: Success - A string containing the requested information based on the closest match.
;              : Failure - An empty string "" if an error occurs.
; Author ......: Dao Van Trong - TRONG.PRO
; ===============================================================================================================================
Func _TimeZone_GetInfoFromOffset($fOffset, $sInfoType = "all")
    Local $sOffsetStr = ""
    Local $sTimeZoneName = ""
    Local $sDisplayName = ""
    Local $fClosestOffset = 0
    Local $fClosestDifference = 99999 ; Start with a large value
    ; Iterate through the global array to find the closest offset
    For $i = 0 To UBound($g_aTimeZones) - 1
        Local $fCurrentOffset = $g_aTimeZones[$i][0]
        Local $fCurrentDifference = Abs($fOffset - $fCurrentOffset)
        If $fCurrentDifference < $fClosestDifference Then
            $fClosestOffset = $fCurrentOffset
            $sTimeZoneName = $g_aTimeZones[$i][1]
            $sDisplayName = $g_aTimeZones[$i][2]
            $fClosestDifference = $fCurrentDifference
        EndIf
        ; Exit early if we find an exact match
        If $fCurrentDifference = 0 Then
            ExitLoop
        EndIf
    Next
    If $sTimeZoneName = "" Then
        Return "" ; Should not happen if array is populated
    EndIf
    ; Format the offset into a string (e.g., "UTC+07:00" or "UTC-03:30")
    $sOffsetStr = _TimeZone_pConvertOffsetToString($fClosestOffset)
    ; Return the requested information
    Switch $sInfoType
        Case "offset"
            Return $sOffsetStr
        Case "name"
            Return $sTimeZoneName
        Case "display"
            Return $sDisplayName
        Case Else
            ; Default "all"
            Return "(" & $sOffsetStr & ") " & $sDisplayName
    EndSwitch
EndFunc   ;==>_TimeZone_GetInfoFromOffset

#EndRegion ;**** Public Functions ****

#Region ;**** Private Functions ****

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pSetWinAPI
; Description....: Sets the time zone using the SetDynamicTimeZoneInformation WinAPI call.
; Parameter(s)...: $sTimeZoneName - The standard Windows time zone name.
; Return Value...: Success - 1
;                  Failure - 0
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pSetWinAPI($sTimeZoneName)
    ; Get the time zone information from the Registry
    Local $aTimeZoneInfo = _TimeZone_pGetInfoFromRegistry($sTimeZoneName)
    If @error Then
        Return 0 ; Failed to get info from registry
    EndIf
    ; Create the DYNAMIC_TIME_ZONE_INFORMATION structure
    ; typedef struct _DYNAMIC_TIME_ZONE_INFORMATION {
    ;   LONG        Bias;
    ;   WCHAR       StandardName[32];
    ;   SYSTEMTIME  StandardDate;
    ;   LONG        StandardBias;
    ;   WCHAR       DaylightName[32];
    ;   SYSTEMTIME  DaylightDate;
    ;   LONG        DaylightBias;
    ;   WCHAR       TimeZoneKeyName[128];
    ;   BOOLEAN     DynamicDaylightTimeDisabled;
    ; } DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
    ; SYSTEMTIME structure: WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds;
    Local $tDTZI = DllStructCreate( _
            "long Bias;" & _
            "wchar StandardName[32];" & _
            "word StdYear;word StdMonth;word StdDayOfWeek;word StdDay;word StdHour;word StdMinute;word StdSecond;word StdMilliseconds;" & _
            "long StandardBias;" & _
            "wchar DaylightName[32];" & _
            "word DltYear;word DltMonth;word DltDayOfWeek;word DltDay;word DltHour;word DltMinute;word DltSecond;word DltMilliseconds;" & _
            "long DaylightBias;" & _
            "wchar TimeZoneKeyName[128];" & _
            "byte DynamicDaylightTimeDisabled" _
            )
    ; Populate the structure
    DllStructSetData($tDTZI, "Bias", $aTimeZoneInfo[0])
    DllStructSetData($tDTZI, "StandardName", $aTimeZoneInfo[1])
    DllStructSetData($tDTZI, "StandardBias", $aTimeZoneInfo[2])
    DllStructSetData($tDTZI, "DaylightName", $aTimeZoneInfo[3])
    DllStructSetData($tDTZI, "DaylightBias", $aTimeZoneInfo[4])
    DllStructSetData($tDTZI, "TimeZoneKeyName", $sTimeZoneName)
    DllStructSetData($tDTZI, "DynamicDaylightTimeDisabled", 0)
    ; Populate StandardDate
    DllStructSetData($tDTZI, "StdYear", $aTimeZoneInfo[5])
    DllStructSetData($tDTZI, "StdMonth", $aTimeZoneInfo[6])
    DllStructSetData($tDTZI, "StdDayOfWeek", $aTimeZoneInfo[7])
    DllStructSetData($tDTZI, "StdDay", $aTimeZoneInfo[8])
    DllStructSetData($tDTZI, "StdHour", $aTimeZoneInfo[9])
    DllStructSetData($tDTZI, "StdMinute", $aTimeZoneInfo[10])
    DllStructSetData($tDTZI, "StdSecond", $aTimeZoneInfo[11])
    DllStructSetData($tDTZI, "StdMilliseconds", $aTimeZoneInfo[12])
    ; Populate DaylightDate
    DllStructSetData($tDTZI, "DltYear", $aTimeZoneInfo[13])
    DllStructSetData($tDTZI, "DltMonth", $aTimeZoneInfo[14])
    DllStructSetData($tDTZI, "DltDayOfWeek", $aTimeZoneInfo[15])
    DllStructSetData($tDTZI, "DltDay", $aTimeZoneInfo[16])
    DllStructSetData($tDTZI, "DltHour", $aTimeZoneInfo[17])
    DllStructSetData($tDTZI, "DltMinute", $aTimeZoneInfo[18])
    DllStructSetData($tDTZI, "DltSecond", $aTimeZoneInfo[19])
    DllStructSetData($tDTZI, "DltMilliseconds", $aTimeZoneInfo[20])
    ; Call SetDynamicTimeZoneInformation
    Local $aResult = DllCall("kernel32.dll", "bool", "SetDynamicTimeZoneInformation", "ptr", DllStructGetPtr($tDTZI))
    If @error Or Not $aResult[0] Then
        Return 0
    EndIf
    ; Broadcast the change message
    _TimeZone_pBroadcastChange()
    Return 1
EndFunc   ;==>_TimeZone_pSetWinAPI

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pGetInfoFromRegistry
; Description....: Reads the binary TZI data from the registry for a specific time zone.
; Parameter(s)...: $sTimeZoneName - The standard Windows time zone name.
; Return Value...: Success - An array ($aInfo[21]) containing the parsed TZI data.
;                  Failure - Returns 0 and sets @error:
;                           1 - Time zone key does not exist in registry.
;                           2 - TZI binary data is missing or unreadable.
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pGetInfoFromRegistry($sTimeZoneName)
    Local $sRegPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\" & $sTimeZoneName
    ; Check if the time zone exists
    Local $sStd = RegRead($sRegPath, "Std")
    If @error Then
        Return SetError(1, 0, 0) ; Error: Cannot read timezone from registry
    EndIf
    Local $sDlt = RegRead($sRegPath, "Dlt")
    Local $bTZI = RegRead($sRegPath, "TZI") ; Read the raw binary data
    If @error Or $bTZI = "" Then
        Return SetError(2, 0, 0) ; Error: Cannot read TZI data from registry
    EndIf
    ; The TZI structure in the registry is 44 bytes:
    ; LONG Bias (4 bytes)
    ; LONG StandardBias (4 bytes)
    ; LONG DaylightBias (4 bytes)
    ; SYSTEMTIME StandardDate (16 bytes)
    ; SYSTEMTIME DaylightDate (16 bytes)
    Local $tTZI_Raw = DllStructCreate("byte[44]")
    DllStructSetData($tTZI_Raw, 1, $bTZI)
    ; Create a new struct to parse the raw data from the pointer
    Local $tData = DllStructCreate("long Bias;long StandardBias;long DaylightBias;" & _
            "word StdYear;word StdMonth;word StdDayOfWeek;word StdDay;word StdHour;word StdMinute;word StdSecond;word StdMilliseconds;" & _
            "word DltYear;word DltMonth;word DltDayOfWeek;word DltDay;word DltHour;word DltMinute;word DltSecond;word DltMilliseconds", _
            DllStructGetPtr($tTZI_Raw))
    ; Create the result array
    Local $aInfo[21]
    $aInfo[0] = DllStructGetData($tData, "Bias")
    $aInfo[1] = $sStd
    $aInfo[2] = DllStructGetData($tData, "StandardBias")
    $aInfo[3] = $sDlt
    $aInfo[4] = DllStructGetData($tData, "DaylightBias")
    ; StandardDate
    $aInfo[5] = DllStructGetData($tData, "StdYear")
    $aInfo[6] = DllStructGetData($tData, "StdMonth")
    $aInfo[7] = DllStructGetData($tData, "StdDayOfWeek")
    $aInfo[8] = DllStructGetData($tData, "StdDay")
    $aInfo[9] = DllStructGetData($tData, "StdHour")
    $aInfo[10] = DllStructGetData($tData, "StdMinute")
    $aInfo[11] = DllStructGetData($tData, "StdSecond")
    $aInfo[12] = DllStructGetData($tData, "StdMilliseconds")
    ; DaylightDate
    $aInfo[13] = DllStructGetData($tData, "DltYear")
    $aInfo[14] = DllStructGetData($tData, "DltMonth")
    $aInfo[15] = DllStructGetData($tData, "DltDayOfWeek")
    $aInfo[16] = DllStructGetData($tData, "DltDay")
    $aInfo[17] = DllStructGetData($tData, "DltHour")
    $aInfo[18] = DllStructGetData($tData, "DltMinute")
    $aInfo[19] = DllStructGetData($tData, "DltSecond")
    $aInfo[20] = DllStructGetData($tData, "DltMilliseconds")
    Return $aInfo
EndFunc   ;==>_TimeZone_pGetInfoFromRegistry

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pBroadcastChange
; Description....: Broadcasts messages to all top-level windows to inform them of a time/setting change.
; Parameter(s)...: None
; Return Value...: 1
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pBroadcastChange()
    Local Const $HWND_BROADCAST = 0xFFFF
    Local Const $WM_SETTINGCHANGE = 0x001A
    Local Const $WM_TIMECHANGE = 0x001E
    Local Const $SMTO_ABORTIFHUNG = 0x0002
    ; Send WM_TIMECHANGE
    DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
            "hwnd", $HWND_BROADCAST, _
            "uint", $WM_TIMECHANGE, _
            "wparam", 0, _
            "lparam", 0, _
            "uint", $SMTO_ABORTIFHUNG, _
            "uint", 5000, _
            "dword*", 0)
    ; Send WM_SETTINGCHANGE for "intl" (international settings)
    DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
            "hwnd", $HWND_BROADCAST, _
            "uint", $WM_SETTINGCHANGE, _
            "wparam", 0, _
            "wstr", "intl", _
            "uint", $SMTO_ABORTIFHUNG, _
            "uint", 5000, _
            "dword*", 0)
    Return 1
EndFunc   ;==>_TimeZone_pBroadcastChange

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pSetTzUtil
; Description....: Fallback method to set the time zone using tzutil.exe.
; Parameter(s)...: $sTimeZone - The standard Windows time zone name.
; Return Value...: Success - 1
;                  Failure - 0
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pSetTzUtil($sTimeZone)
    Local $iResult = RunWait(@ComSpec & ' /c tzutil /s "' & $sTimeZone & '"', @WindowsDir & '\System32', @SW_HIDE)
    If $iResult = 0 Then
        _TimeZone_pBroadcastChange() ; Broadcast the change
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>_TimeZone_pSetTzUtil

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pInitArray
; Description....: Initializes the global array of all time zones.
;                  [Offset, "Standard Name", "Display Name"]
; Parameter(s)...: None
; Return Value...: A 2D array [139][3]
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pInitArray()
    Local $aTimeZones[139][3] = [[-12, "Dateline Standard Time", "International Date Line West"], _
            [-11, "UTC-11", "Coordinated Universal Time-11"], _
            [-10, "Hawaiian Standard Time", "Hawaii"], _
            [-10, "Aleutian Standard Time", "Aleutian Islands"], _
            [-9.5, "Marquesas Standard Time", "Marquesas Islands"], _
            [-9, "Alaskan Standard Time", "Alaska"], _
            [-9, "UTC-09", "Coordinated Universal Time-09"], _
            [-8, "Pacific Standard Time", "Pacific Time (US & Canada)"], _
            [-8, "Pacific Standard Time (Mexico)", "Baja California"], _
            [-8, "UTC-08", "Coordinated Universal Time-08"], _
            [-7, "Mountain Standard Time", "Mountain Time (US & Canada)"], _
            [-7, "US Mountain Standard Time", "Arizona"], _
            [-7, "Mountain Standard Time (Mexico)", "La Paz, Mazatlan"], _
            [-7, "Yukon Standard Time", "Yukon"], _
            [-6, "Central Standard Time", "Central Time (US & Canada)"], _
            [-6, "Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey"], _
            [-6, "Central America Standard Time", "Central America"], _
            [-6, "Canada Central Standard Time", "Saskatchewan"], _
            [-6, "Easter Island Standard Time", "Easter Island"], _
            [-5, "Eastern Standard Time", "Eastern Time (US & Canada)"], _
            [-5, "US Eastern Standard Time", "Indiana (East)"], _
            [-5, "SA Pacific Standard Time", "Bogota, Lima, Quito, Rio Branco"], _
            [-5, "Eastern Standard Time (Mexico)", "Chetumal"], _
            [-5, "Cuba Standard Time", "Havana"], _
            [-5, "Haiti Standard Time", "Haiti"], _
            [-5, "Turks And Caicos Standard Time", "Turks and Caicos"], _
            [-4, "Atlantic Standard Time", "Atlantic Time (Canada)"], _
            [-4, "SA Western Standard Time", "Georgetown, La Paz, Manaus, San Juan"], _
            [-4, "Pacific SA Standard Time", "Santiago"], _
            [-4, "Central Brazilian Standard Time", "Cuiaba"], _
            [-4, "Venezuela Standard Time", "Caracas"], _
            [-3.5, "Newfoundland Standard Time", "Newfoundland"], _
            [-3, "E. South America Standard Time", "Brasilia"], _
            [-3, "SA Eastern Standard Time", "Cayenne, Fortaleza"], _
            [-3, "Argentina Standard Time", "City of Buenos Aires"], _
            [-3, "Paraguay Standard Time", "Asuncion"], _
            [-3, "Montevideo Standard Time", "Montevideo"], _
            [-3, "Magallanes Standard Time", "Punta Arenas"], _
            [-3, "Tocantins Standard Time", "Araguaina"], _
            [-3, "Bahia Standard Time", "Salvador"], _
            [-3, "Saint Pierre Standard Time", "Saint Pierre and Miquelon"], _
            [-2, "Greenland Standard Time", "Greenland"], _
            [-2, "UTC-02", "Coordinated Universal Time-02"], _
            [-1, "Azores Standard Time", "Azores"], _
            [-1, "Cape Verde Standard Time", "Cabo Verde Is."], _
            [0, "GMT Standard Time", "Dublin, Edinburgh, Lisbon, London"], _
            [0, "Greenwich Standard Time", "Monrovia, Reykjavik"], _
            [0, "Sao Tome Standard Time", "Sao Tome"], _
            [0, "UTC", "Coordinated Universal Time"], _
            [1, "W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"], _
            [1, "Romance Standard Time", "Brussels, Copenhagen, Madrid, Paris"], _
            [1, "Central Europe Standard Time", "Belgrade, Bratislava, Budapest, Ljubljana, Prague"], _
            [1, "Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb"], _
            [1, "W. Central Africa Standard Time", "West Central Africa"], _
            [1, "Morocco Standard Time", "Casablanca"], _
            [2, "FLE Standard Time", "Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius"], _
            [2, "GTB Standard Time", "Athens, Bucharest"], _
            [2, "E. Europe Standard Time", "Chisinau"], _
            [2, "South Africa Standard Time", "Harare, Pretoria"], _
            [2, "Egypt Standard Time", "Cairo"], _
            [2, "Israel Standard Time", "Jerusalem"], _
            [2, "Middle East Standard Time", "Beirut"], _
            [2, "West Bank Standard Time", "Gaza, Hebron"], _
            [2, "Kaliningrad Standard Time", "Kaliningrad"], _
            [2, "Sudan Standard Time", "Khartoum"], _
            [2, "South Sudan Standard Time", "Juba"], _
            [2, "Libya Standard Time", "Tripoli"], _
            [2, "Namibia Standard Time", "Windhoek"], _
            [3, "Russian Standard Time", "Moscow, St. Petersburg"], _
            [3, "Turkey Standard Time", "Istanbul"], _
            [3, "Arab Standard Time", "Kuwait, Riyadh"], _
            [3, "Arabic Standard Time", "Baghdad"], _
            [3, "E. Africa Standard Time", "Nairobi"], _
            [3, "Belarus Standard Time", "Minsk"], _
            [3, "Jordan Standard Time", "Amman"], _
            [3, "Syria Standard Time", "Damascus"], _
            [3, "Volgograd Standard Time", "Volgograd"], _
            [3.5, "Iran Standard Time", "Tehran"], _
            [4, "Arabian Standard Time", "Abu Dhabi, Muscat"], _
            [4, "Russia Time Zone 3", "Izhevsk, Samara"], _
            [4, "Astrakhan Standard Time", "Astrakhan, Ulyanovsk"], _
            [4, "Saratov Standard Time", "Saratov"], _
            [4, "Caucasus Standard Time", "Yerevan"], _
            [4, "Azerbaijan Standard Time", "Baku"], _
            [4, "Georgian Standard Time", "Tbilisi"], _
            [4, "Mauritius Standard Time", "Port Louis"], _
            [4.5, "Afghanistan Standard Time", "Kabul"], _
            [5, "West Asia Standard Time", "Ashgabat, Tashkent"], _
            [5, "Ekaterinburg Standard Time", "Ekaterinburg"], _
            [5, "Pakistan Standard Time", "Islamabad, Karachi"], _
            [5, "Qyzylorda Standard Time", "Astana"], _
            [5.5, "India Standard Time", "Chennai, Kolkata, Mumbai, New Delhi"], _
            [5.5, "Sri Lanka Standard Time", "Sri Jayawardenepura"], _
            [5.75, "Nepal Standard Time", "Kathmandu"], _
            [6, "Central Asia Standard Time", "Bishkek"], _
            [6, "Omsk Standard Time", "Omsk"], _
            [6, "Bangladesh Standard Time", "Dhaka"], _
            [6.5, "Myanmar Standard Time", "Yangon (Rangoon)"], _
            [7, "SE Asia Standard Time", "Bangkok, Hanoi, Jakarta"], _
            [7, "N. Central Asia Standard Time", "Novosibirsk"], _
            [7, "North Asia Standard Time", "Krasnoyarsk"], _
            [7, "Altai Standard Time", "Barnaul, Gorno-Altaysk"], _
            [7, "Tomsk Standard Time", "Tomsk"], _
            [7, "W. Mongolia Standard Time", "Hovd"], _
            [8, "China Standard Time", "Beijing, Chongqing, Hong Kong, Urumqi"], _
            [8, "Singapore Standard Time", "Kuala Lumpur, Singapore"], _
            [8, "Taipei Standard Time", "Taipei"], _
            [8, "W. Australia Standard Time", "Perth"], _
            [8, "North Asia East Standard Time", "Irkutsk"], _
            [8, "Ulaanbaatar Standard Time", "Ulaanbaatar"], _
            [8.75, "Aus Central W. Standard Time", "Eucla"], _
            [9, "Tokyo Standard Time", "Osaka, Sapporo, Tokyo"], _
            [9, "Korea Standard Time", "Seoul"], _
            [9, "North Korea Standard Time", "Pyongyang"], _
            [9, "Yakutsk Standard Time", "Yakutsk"], _
            [9, "Transbaikal Standard Time", "Chita"], _
            [9.5, "AUS Central Standard Time", "Darwin"], _
            [9.5, "Cen. Australia Standard Time", "Adelaide"], _
            [10, "AUS Eastern Standard Time", "Canberra, Melbourne, Sydney"], _
            [10, "E. Australia Standard Time", "Brisbane"], _
            [10, "Tasmania Standard Time", "Hobart"], _
            [10, "Vladivostok Standard Time", "Vladivostok"], _
            [10, "West Pacific Standard Time", "Guam, Port Moresby"], _
            [10.5, "Lord Howe Standard Time", "Lord Howe Island"], _
            [11, "Central Pacific Standard Time", "Solomon Is., New Caledonia"], _
            [11, "Magadan Standard Time", "Magadan"], _
            [11, "Russia Time Zone 10", "Chokurdakh"], _
            [11, "Sakhalin Standard Time", "Sakhalin"], _
            [11, "Bougainville Standard Time", "Bougainville Island"], _
            [11, "Norfolk Standard Time", "Norfolk Island"], _
            [12, "New Zealand Standard Time", "Auckland, Wellington"], _
            [12, "Fiji Standard Time", "Fiji"], _
            [12, "Russia Time Zone 11", "Anadyr, Petropavlovsk-Kamchatsky"], _
            [12, "UTC+12", "Coordinated Universal Time+12"], _
            [12.75, "Chatham Islands Standard Time", "Chatham Islands"], _
            [13, "Tonga Standard Time", "Nuku'alofa"], _
            [13, "Samoa Standard Time", "Samoa"], _
            [13, "UTC+13", "Coordinated Universal Time+13"], _
            [14, "Line Islands Standard Time", "Kiritimati Island"]]
    Return $aTimeZones
EndFunc   ;==>_TimeZone_pInitArray

; -------------------------------------------------------------------------------------------------------------------------------
; Name...........: _TimeZone_pConvertOffsetToString
; Description....: Converts a numeric offset to a formatted UTC string.
; Parameter(s)...: $fOffset - The numeric offset (e.g., 7, -5.5)
; Return Value...: A string (e.g., "UTC+07:00", "UTC-05:30", "UTC+00:00")
; -------------------------------------------------------------------------------------------------------------------------------
Func _TimeZone_pConvertOffsetToString($fOffset)
    Local $sSign = "+"
    If $fOffset < 0 Then
        $sSign = "-"
    EndIf
    Local $fAbsOffset = Abs($fOffset)
    Local $iHours = Int($fAbsOffset)
    Local $iMinutes = Round(($fAbsOffset - $iHours) * 60)
    Return "UTC" & $sSign & StringFormat("%02d", $iHours) & ":" & StringFormat("%02d", $iMinutes)
EndFunc   ;==>_TimeZone_pConvertOffsetToString

#EndRegion ;**** Private Functions ****

#Region ;**** Example ****
; ; Uncomment the section below to run an example
; ; Requires #RequireAdmin to set the time zone
;
; #RequireAdmin
;
; ; Get current time zone
; Local $sCurrent = _TimeZone_Get()
; ConsoleWrite("Current Time Zone: " & $sCurrent & @CRLF)
;
; ; Test setting by offset
; ConsoleWrite("Attempting to set to UTC+9 (Tokyo)..." & @CRLF)
; _TimeZone_Set("UTC+9")
; ConsoleWrite("New Time Zone: " & _TimeZone_Get() & @CRLF)
;
; Sleep(2000)
;
; ; Test setting by name
; ConsoleWrite("Attempting to set to 'Pacific Standard Time' (UTC-8)..." & @CRLF)
; _TimeZone_Set("Pacific Standard Time")
; ConsoleWrite("New Time Zone: " & _TimeZone_Get() & @CRLF)
;
; Sleep(2000)
;
; ; Revert to original
; ConsoleWrite("Reverting to original: " & $sCurrent & @CRLF)
; _TimeZone_Set($sCurrent)
; ConsoleWrite("Final Time Zone: " & _TimeZone_Get() & @CRLF)
;
; ; Test lookup functions
; ConsoleWrite("Info for UTC+7: " & _TimeZone_GetInfoFromOffset(7) & @CRLF)
; ConsoleWrite("Info for UTC-5.5: " & _TimeZone_GetInfoFromOffset(-5.5) & @CRLF)
; ConsoleWrite("Name for 'Bangkok, Hanoi, Jakarta': " & _TimeZone_GetNameFromDisplay("Bangkok, Hanoi, Jakarta", "name") & @CRLF)
; ConsoleWrite("Display for 'SE Asia Standard Time': " & _TimeZone_GetDisplayFromeName("SE Asia Standard Time") & @CRLF)

#EndRegion ;**** Example ****

eg in udf

Enjoy my work? Buy me a 🍻 or tip via ❤️ PayPal

Posted

Nice work, but regard timezones as a can of venimous snakes. General time keeping is even much, MUCH worse.

tz data is only valid at a given point in time (how do you count time?) and for a loosely specified region. For example, look at https://time.is/fr/time_zone_news

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...