Weil wir uns gerade so intensiv mit dem Thema Zeit beschäftigen, kommt hier auch noch ein Skript von mir. Es zeigt die in der Registrierung gespeicherten Daten der einzelnen Zeitzonen an.
Im linken ListView werden der Name des Registrierungsschlüssels für die Zeitzone und die (zumindest zu guten alten XP-Zeiten) angezeigte Beschreibung angezeigt.
Das rechte ListView zeigt die Werte der im linken ListView ausgewählten Zeitzone an:
- Die erste Zeile enthält die aktuellen Werte inklusive der Daten für die Sommer- bzw. Winterzeit an, sofern es die gibt.
- Die weiteren Zeilen enthalten die 'dynamischen' Werte für den Fall, dass sich im Laufe der Jahre die Daten der Umstellung verändert haben.
- Die angezeigten 'Bias' Werte sind Abweichungen von der Universalzeit (UTC) in Minuten. Die angezeigten Daten entsprechen immer der lokale Zeitzone.
Code: Select all
#NoEnv
SetBatchLines, -1
; --------------------------------------------------------------------------------------------------------------------------------
; Read the registry values
TZ := New TimeZones
; --------------------------------------------------------------------------------------------------------------------------------
Gui, Margin, 8, 8
Gui, Add, ListView, xm -Multi w500 r25 vLVReg gLVKey AltSubmit +LV0x14000, Reg Key|Display Name
LocalZone := TZ.Local
LocalRow := 1
For K, V In TZ.Zones {
Row := LV_Add("", K, V.Display)
If (K = LocalZone)
LocalRow := Row
}
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(2, "AutoHdr")
Gui, Add, ListView, x+m Grid -Multi w500 r25 vLVDST hwndHLV +LV0x10000
, Year|UTC Bias|DST Start|DST Bias|DST End|Std Bias|%A_Space%
LV_Add("", "", "", "0000-00-00 00:00:00", "", "0000-00-00 00:00:00")
Loop, 7
LV_ModifyCol(A_Index, "AutoHdr")
LV_Delete(1)
LV_ModifyCol(1, "Integer")
LV_ModifyCol(2, "Integer")
LV_ModifyCol(4, "Integer")
LV_ModifyCol(6, "Integer")
Gui, Show, , TimeZones - DST
Gui, ListView, LVReg
LV_Modify(LocalRow, "Focus Select Vis")
Return
; --------------------------------------------------------------------------------------------------------------------------------
GuiClose:
GuiEscape:
ExitApp
; --------------------------------------------------------------------------------------------------------------------------------
LVKey:
Critical
If (A_GuiEvent == "I") && InStr(ErrorLevel, "S", 1) {
Gui, ListView, LVReg
LV_GetText(TimeZone, A_EventInfo)
Current := TZ.Zones[TimeZone, "Current"]
Dynamic := TZ.Zones[TimeZone, "Dynamic"]
Gui, ListView, LVDST
LV_Delete()
LV_Add("", "", Current.Bias, Current.DltD, Current.DltB, Current.StdD, Current.StdB)
For DynYear, Values In Dynamic
LV_Add("", DynYear, Values.Bias, Values.DltD, Values.DltB, Values.StdD, Values.StdB)
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
Class TimeZones {
__New(P*) {
Static RegKey := "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
RegRead, LocalZone, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation, TimeZoneKeyName
Zones := {}
ZoneCount := 0
Loop, Reg, %RegKey%, K
{
ZoneCount++
TimeZone := A_LoopRegName
RegRead, RegDisp, %RegKey%\%TimeZone%, Display
RegRead, RegTZI, %RegKey%\%TimeZone%, TZI
This.ConvertTZI(RegTZI, TZI)
Current := This.GetValues(&TZI)
Dynamic := {}
Loop, Reg, %RegKey%\%TimeZone%\Dynamic DST, V
{
If A_LoopRegName Is Date
{
DynYear := A_LoopRegName
RegRead, RegTZI
This.ConvertTZI(RegTZI, TZI)
Dynamic[DynYear] := This.GetValues(&TZI, DynYear)
}
}
Zones[TimeZone] := {Display: RegDisp, Current: Current, Dynamic: Dynamic}
}
This.Local := LocalZone
This.Count := ZoneCount
This.Zones := Zones
}
; -----------------------------------------------------------------------------------------------------------------------------
; Retrieves the DST values from a REG_TZI_FORMAT structure.
; -----------------------------------------------------------------------------------------------------------------------------
GetValues(Pointer, DynYear := 0) {
Bias := NumGet(Pointer + 0, "Int") ; Bias
DltD := This.ST2DT(Pointer + 28, DynYear) ; DaylightDate
DltB := DltD ? NumGet(Pointer + 8, "Int") : "" ; DaylightBias
StdD := This.ST2DT(Pointer + 12, DynYear) ; StandardDate
StdB := StdD ? NumGet(Pointer + 4, "Int") : "" ; StandardBias
Return {Bias: Bias, DltD: DltD, DltB: DltB, StdD: StdD, StdB: StdB}
}
; -----------------------------------------------------------------------------------------------------------------------------
; Retrieves a date-time string from a SYSTEMTIME structure using the rules defined for TIME_ZONE_INFORMATION structures.
; -> msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
; -----------------------------------------------------------------------------------------------------------------------------
ST2DT(Pointer, DynYear := 0) {
Year := NumGet(Pointer + 0, "Short")
Month := NumGet(Pointer + 2, "Short")
WDay := NumGet(Pointer + 4, "Short") + 1
Day := NumGet(Pointer + 6, "Short")
Hour := NumGet(Pointer + 8, "Short")
Min := NumGet(Pointer + 10, "Short")
Sec := NumGet(Pointer + 12, "Short")
If (Year = 0) && (Month <> 0) {
Year := DynYear ? DynYear : A_YYYY
Day := This.WDay2Day(Year, Month, WDay, Day)
}
Return (Month = 0 ? "" : Format("{:04}-{:02}-{:02} {:02}:{:02}:{:02}", Year, Month, Day, Hour, Min, Sec))
}
; -----------------------------------------------------------------------------------------------------------------------------
; Calculates the day of the given year and month specified by WDay and occurence.
; -----------------------------------------------------------------------------------------------------------------------------
WDay2Day(Year, Month, WDay, Occurence) {
YearMonth := Format("{:04}{:02}01", Year, Month)
If YearMonth Is Not Date
Return 0
If WDay Not Between 1 And 7
Return 0
If Occurence Not Between 1 And 5 ; 5 = last occurence
Return 0
FormatTime, WD, %YearMonth%, WDay
While (WD <> WDay) {
YearMonth += 1, D
FormatTime, WD, %YearMonth%, WDay
}
While (A_Index <= Occurence) && (SubStr(YearMonth, 5, 2) = Month) {
Day := SubStr(YearMonth, 7, 2)
YearMonth += 7, D
}
Return Day
}
; -----------------------------------------------------------------------------------------------------------------------------
; Converts registry TZI values into a REG_TZI_FORMAT structure.
; -> msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
; -----------------------------------------------------------------------------------------------------------------------------
ConvertTZI(RegTZI, ByRef TZI) {
VarSetCapacity(TZI, 44, 0)
IR := -1
Addr := &TZI
Loop, 4 ; Bias - 4 bytes
Addr := NumPut("0x" . SubStr(RegTZI, IR += 2, 2), Addr + 0, "UChar")
Loop, 4 ; StandardBias - 4 bytes
Addr := NumPut("0x" . SubStr(RegTZI, IR += 2, 2), Addr + 0, "UChar")
Loop, 4 ; DaylightBias - 4 bytes
Addr := NumPut("0x" . SubStr(RegTZI, IR += 2, 2), Addr + 0, "UChar")
Loop, 16 ; StandardDate - 16 bytes
Addr := NumPut("0x" . SubStr(RegTZI, IR += 2, 2), Addr + 0, "UChar")
Loop, 16 ; DaylightDate - 16 bytes
Addr := NumPut("0x" . SubStr(RegTZI, IR += 2, 2), Addr + 0, "UChar")
}
}